Sql 从所有组返回1行

Sql 从所有组返回1行,sql,sql-server,tsql,Sql,Sql Server,Tsql,编辑以包含sql代码: CREATE TABLE TMP_PRODUCTS (STORE INT, UPC INT, PROMOCODE CHAR(3), FORSALE CHAR(1)) INSERT INTO TMP_PRODUCTS VALUES (100,1,'123','Y'), (100,2,'123','Y'), (100,3,'123','N'), (100,4,'124','Y'), (100,5,'124','N'), (100,6,'124','N'), (100,7,'

编辑以包含sql代码:

CREATE TABLE TMP_PRODUCTS (STORE INT, UPC INT, PROMOCODE CHAR(3), FORSALE CHAR(1))

INSERT INTO TMP_PRODUCTS VALUES
(100,1,'123','Y'),
(100,2,'123','Y'),
(100,3,'123','N'),
(100,4,'124','Y'),
(100,5,'124','N'),
(100,6,'124','N'),
(100,7,'125','N'),
(100,8,'125','N'),
(100,9,'125','N');

SELECT
    STORE,
    UPC,
    PROMOCODE,
    DENSE_RANK() OVER (PARTITION BY STORE ORDER BY PROMOCODE) AS 'GroupCode'
FROM
    TMP_PRODUCTS
WHERE
    FORSALE = 'Y'
我需要返回所有PROMOCODE组中FORSALE='Y'所在的所有行,以及FORSALE='N'所在的所有组中至少一行。在本例中,组125中的所有产品都是FORSALE='N',但我至少需要返回一行。以下是我当前获得的输出:

STORE   UPC     PROMOCODE   GroupCode   FORSALE
100     1       123         1           Y
100     2       123         1           Y
100     4       124         2           Y
但这是我想要得到的理想输出:

STORE   UPC     PROMOCODE   GroupCode   FORSALE
100     1       123         1           Y
100     2       123         1           Y
100     4       124         2           Y
100     7       125         3           N
从促销代码123和124返回1行也是完全可以接受的,即使它们已经有一些FORSALE='Y'项目。因此,这也是可以接受的结果:

STORE   UPC     PROMOCODE   GroupCode   FORSALE
100     1       123         1           Y
100     2       123         1           Y
100     3       123         1           N
100     4       124         2           Y
100     5       124         2           N
100     7       125         3           N

您可以通过一个附加的“行号”窗口功能来实现这一点,该功能始终包括来自每个组的1行,而不考虑Y/N

select STORE, UPC, PROMOCODE, Dense_Rank() over (partition by STORE order by PROMOCODE) GROUPCODE, FORSALE
from (
    select * , Row_Number() over(partition by STORE, PROMOCODE order by UPC) rn
    from TMP_PRODUCTS
)x
where FORSALE = 'Y' or rn=1

您可以通过一个附加的“行号”窗口功能来实现这一点,该功能始终包括来自每个组的1行,而不考虑Y/N

select STORE, UPC, PROMOCODE, Dense_Rank() over (partition by STORE order by PROMOCODE) GROUPCODE, FORSALE
from (
    select * , Row_Number() over(partition by STORE, PROMOCODE order by UPC) rn
    from TMP_PRODUCTS
)x
where FORSALE = 'Y' or rn=1

如果我理解正确,您需要的逻辑是:

SELECT STORE, UPC, PROMOCODE,
       DENSE_RANK() OVER (PARTITION BY STORE ORDER BY PROMOCODE) AS GroupCode
FROM (SELECT P.*,
             ROW_NUMBER() OVER (PARTITION BY STORE, PROMOCODE, FORSALE ORDER BY (SELECT NULL)) as seqnum
      FROM TMP_PRODUCTS P
     ) P
WHERE FORSALE = 'Y' OR seqnum = 1;

如果我理解正确,您需要的逻辑是:

SELECT STORE, UPC, PROMOCODE,
       DENSE_RANK() OVER (PARTITION BY STORE ORDER BY PROMOCODE) AS GroupCode
FROM (SELECT P.*,
             ROW_NUMBER() OVER (PARTITION BY STORE, PROMOCODE, FORSALE ORDER BY (SELECT NULL)) as seqnum
      FROM TMP_PRODUCTS P
     ) P
WHERE FORSALE = 'Y' OR seqnum = 1;

fiddle很好,但这里的问题应该是自包含的,即指定了样本表数据和预期结果-全部作为格式化文本(而不是图像)。fiddle很好,但这里的问题应该是自包含的,即指定了样本表数据和预期结果-全部作为格式化文本(而不是图像)我认为这并不能保证一行是
N
。我认为这可能只是顺序问题,事后来看,如果行号顺序是按forsale排序的,那么这意味着每个promocode组都会有一个“N”如果它作为第一行存在,那么它将被包括在内。我认为这不能保证一行是
N
。我认为这可能只是顺序问题,事后来看,如果行数顺序是按forsale排序的,那么这意味着如果它作为第一行存在,那么每个promocode组将始终有一个“N”,因此将被包括在内。