Sql 从所有组返回1行
编辑以包含sql代码: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,'
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”,因此将被包括在内。