在SQL中查询此搜索的不同方法?
我在自学MS-SQL,并试图找到不同的方法,从这3个表中找出2012年按地区分组的已支付和未支付索赔的数量。如果有返回日期,则索赔未支付。如果返回日期为空,则索赔已支付 我会附上我运行过的代码,但我不确定是否有更好的方法 谢谢 代码如下:在SQL中查询此搜索的不同方法?,sql,sql-server,sql-server-2008,join,Sql,Sql Server,Sql Server 2008,Join,我在自学MS-SQL,并试图找到不同的方法,从这3个表中找出2012年按地区分组的已支付和未支付索赔的数量。如果有返回日期,则索赔未支付。如果返回日期为空,则索赔已支付 我会附上我运行过的代码,但我不确定是否有更好的方法 谢谢 代码如下: SET dateformat ymd; CREATE TABLE Claims ( ClaimID INT, SubID INT, [Claim Date] DATETIME ); CREATE
SET dateformat ymd;
CREATE TABLE Claims
(
ClaimID INT,
SubID INT,
[Claim Date] DATETIME
);
CREATE TABLE Phoneship
(
ClaimID INT,
[Shipping Number] INT,
[Claim Date] DATETIME,
[Ship Date] DATETIME,
[Returned Date] DATETIME
);
CREATE TABLE Enrollment
(
SubID INT,
Enrollment_Date DATETIME,
Channel NVARCHAR(255),
Region NVARCHAR(255),
Status FLOAT,
Drop_Date DATETIME
);
INSERT INTO [Phoneship]
([ClaimID],
[Shipping Number],
[Claim Date],
[Ship Date],
[Returned Date])
VALUES (102,
201,
'2011-10-13 00:00:00',
'2011-10-14 00:00:00',
NULL);
INSERT INTO [Phoneship]
([ClaimID],
[Shipping Number],
[Claim Date],
[Ship Date],
[Returned Date])
VALUES (103,
202,
'2011-11-02 00:00:00',
'2011-11-03 00:00:00',
'2011-11-20 00:00:00');
INSERT INTO [Phoneship]
([ClaimID],
[Shipping Number],
[Claim Date],
[Ship Date],
[Returned Date])
VALUES (103,
203,
'2011-11-02 00:00:00',
'2011-11-22 00:00:00',
NULL);
INSERT INTO [Phoneship]
([ClaimID],
[Shipping Number],
[Claim Date],
[Ship Date],
[Returned Date])
VALUES (105,
204,
'2012-01-16 00:00:00',
'2012-01-17 00:00:00',
NULL);
INSERT INTO [Phoneship]
([ClaimID],
[Shipping Number],
[Claim Date],
[Ship Date],
[Returned Date])
VALUES (106,
205,
'2012-02-15 00:00:00',
'2012-02-16 00:00:00',
'2012-02-26 00:00:00');
INSERT INTO [Phoneship]
([ClaimID],
[Shipping Number],
[Claim Date],
[Ship Date],
[Returned Date])
VALUES (106,
206,
'2012-02-15 00:00:00',
'2012-02-27 00:00:00',
'2012-03-06 00:00:00');
INSERT INTO [Phoneship]
([ClaimID],
[Shipping Number],
[Claim Date],
[Ship Date],
[Returned Date])
VALUES (107,
207,
'2012-03-12 00:00:00',
'2012-03-13 00:00:00',
NULL);
INSERT INTO [Phoneship]
([ClaimID],
[Shipping Number],
[Claim Date],
[Ship Date],
[Returned Date])
VALUES (108,
208,
'2012-05-11 00:00:00',
'2012-05-12 00:00:00',
NULL);
INSERT INTO [Phoneship]
([ClaimID],
[Shipping Number],
[Claim Date],
[Ship Date],
[Returned Date])
VALUES (109,
209,
'2012-05-13 00:00:00',
'2012-05-14 00:00:00',
'2012-05-28 00:00:00');
INSERT INTO [Phoneship]
([ClaimID],
[Shipping Number],
[Claim Date],
[Ship Date],
[Returned Date])
VALUES (109,
210,
'2012-05-13 00:00:00',
'2012-05-30 00:00:00',
NULL);
INSERT INTO [Claims]
([ClaimID],
[SubID],
[Claim Date])
VALUES (101,
12345678,
'2011-03-06 00:00:00');
INSERT INTO [Claims]
([ClaimID],
[SubID],
[Claim Date])
VALUES (102,
12347190,
'2011-10-13 00:00:00');
INSERT INTO [Claims]
([ClaimID],
[SubID],
[Claim Date])
VALUES (103,
12348723,
'2011-11-02 00:00:00');
INSERT INTO [Claims]
([ClaimID],
[SubID],
[Claim Date])
VALUES (104,
12349745,
'2011-11-09 00:00:00');
INSERT INTO [Claims]
([ClaimID],
[SubID],
[Claim Date])
VALUES (105,
12347190,
'2012-01-16 00:00:00');
INSERT INTO [Claims]
([ClaimID],
[SubID],
[Claim Date])
VALUES (106,
12349234,
'2012-02-15 00:00:00');
INSERT INTO [Claims]
([ClaimID],
[SubID],
[Claim Date])
VALUES (107,
12350767,
'2012-03-12 00:00:00');
INSERT INTO [Claims]
([ClaimID],
[SubID],
[Claim Date])
VALUES (108,
12350256,
'2012-05-11 00:00:00');
INSERT INTO [Claims]
([ClaimID],
[SubID],
[Claim Date])
VALUES (109,
12347701,
'2012-05-13 00:00:00');
INSERT INTO [Claims]
([ClaimID],
[SubID],
[Claim Date])
VALUES (110,
12350256,
'2012-05-15 00:00:00');
INSERT INTO [Claims]
([ClaimID],
[SubID],
[Claim Date])
VALUES (111,
12350767,
'2012-06-30 00:00:00');
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12345678,
'2011-01-05 00:00:00',
'Retail',
'Southeast',
1,
NULL);
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12346178,
'2011-03-13 00:00:00',
'Indirect Dealers',
'West',
1,
NULL);
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12346679,
'2011-05-19 00:00:00',
'Indirect Dealers',
'Southeast',
0,
'2012-03-15 00:00:00');
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12347190,
'2011-07-25 00:00:00',
'Retail',
'Northeast',
0,
'2012-05-21 00:00:00');
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12347701,
'2011-08-14 00:00:00',
'Indirect Dealers',
'West',
1,
NULL);
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12348212,
'2011-09-30 00:00:00',
'Retail',
'West',
1,
NULL);
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12348723,
'2011-10-20 00:00:00',
'Retail',
'Southeast',
1,
NULL);
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12349234,
'2012-01-06 00:00:00',
'Indirect Dealers',
'West',
0,
'2012-02-14 00:00:00');
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12349745,
'2012-01-26 00:00:00',
'Retail',
'Northeast',
0,
'2012-04-15 00:00:00');
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12350256,
'2012-02-11 00:00:00',
'Retail',
'Southeast',
1,
NULL);
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12350767,
'2012-03-02 00:00:00',
'Indirect Dealers',
'West',
1,
NULL);
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12351278,
'2012-04-18 00:00:00',
'Retail',
'Midwest',
1,
NULL);
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12351789,
'2012-05-08 00:00:00',
'Indirect Dealers',
'West',
0,
'2012-07-04 00:00:00');
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12352300,
'2012-06-24 00:00:00',
'Retail',
'Midwest',
1,
NULL);
INSERT INTO [Enrollment]
([SubID],
[Enrollment_Date],
[Channel],
[Region],
[Status],
[Drop_Date])
VALUES (12352811,
'2012-06-25 00:00:00',
'Retail',
'Southeast',
1,
NULL);
和问题1
SELECT Count(ClaimID) AS 'Paid Claim',
(SELECT Count(ClaimID)
FROM dbo.phoneship
WHERE [returned date] IS NOT NULL) AS 'Unpaid Claim'
FROM dbo.Phoneship
WHERE [Returned Date] IS NULL
GROUP BY claimid
问题2
SELECT Count(*) AS 'Paid Claims',
(SELECT Count(*)
FROM dbo.Phoneship
WHERE [Returned Date] IS NOT NULL) AS 'Unpaid Claims'
FROM dbo.Phoneship
WHERE [Returned Date] IS NULL;
问题3
Select Distinct(C.[Shipping Number]), Count(C.ClaimID) AS 'COUNT ClaimID',
A.Region, A.SubID
From dbo.HSEnrollment A
Inner Join dbo.Claims B On A.SubId = B.SubId
Inner Join dbo.Phoneship C On B.ClaimID = C.ClaimID
Where C.[Returned Date] IS NULL
Group By A.Region, A.Subid, C.ClaimID, C.[Shipping Number] Order By A.Region
您需要将所有表连接在一起以获得区域。此版本假定每个索赔最多有一个on Phoneship记录:
SELECT e.region, count(*) as numclaims,
sum(case when ps.ReturnedDate is not null then 1 else 0 end) AS 'Paid Claim',
sum(case when ps.ReturnedDate is null then 1 else 0 end) AS 'Unpaid Claim'
FROM claims c join
enrollment e
on c.sub_id = e.sub_id left outer join
Phoneship ps
on ps.claimid = c.claimdid
WHERE [Returned Date] IS NULL
GROUP BY e.region
如果有多个,那么计数将被关闭,因为每个电话将被计数,而不是每个索赔。要解决此问题,请将两个总和更改为:
count(distinct case when ps.ReturnedDate is not null then c.claimid end)
count(distinct case when ps.ReturnedDate is null then c.claimid end)
很难回答这个问题,因为我知道你在问什么,但还有很多其他小问题导致你的查询困难 我的答案
因此,要回答您问题的核心,我会做什么,如果且仅当我正确地解释了您的表结构(后面还有更多内容) 我没有包括索赔的数量,因为这会使数字偏离。我包含了两个查询,最终查询和细分查询。对于总和(因为您正在学习),我使用ROLLUP获得每个分组列的总和
SELECT
e.Region,
paid = SUM(CASE WHEN p.[Returned Date] IS NULL THEN 1 ELSE 0 END),
unpaid = SUM(CASE WHEN p.[Returned Date] IS NULL THEN 0 ELSE 1 END)
FROM claims c
INNER JOIN enrollment e
ON e.SubID = c.SubID
INNER JOIN phoneship p
ON p.ClaimID = c.ClaimID
GROUP BY e.Region
WITH ROLLUP
故障这是使用内部虚拟表(结果表-结果集等)的子选择的细分查询。我这样做是为了证明一点
SELECT
x.Region,
-- if the Returned Date is null then add 1, otherwise add 0
paid = SUM(CASE WHEN x.ReturnedDate IS NULL THEN 1 ELSE 0 END),
-- if the Returned Date is null then add 0, otherwise add 1
unpaid = SUM(CASE WHEN x.ReturnedDate IS NULL THEN 0 ELSE 1 END)
FROM
(
-- Run this inner query to see what data you are actually working with
-- for your grouping/sums
SELECT
c.ClaimID,
c.SubID,
E = '#', -- This is just a separator
e_SubID = e.SubID, -- This is equivalent to saying e.SubID AS e_SubID
e.Region,
P = '#', -- This is just a separator
p_ClaimID = p.ClaimID,
ShippingNo = p.[Shipping Number], -- Getting rid of those nasty spaces
ReturnedDate = p.[Returned Date]
FROM claims c
INNER JOIN enrollment e
ON e.SubID = c.SubID
-- Initially this was a LEFT JOIN but you are missing Claims in your
-- Phoneship table which will produce bogus results, therefore the
-- INNER JOIN will filter out any rows that don't match
INNER JOIN phoneship p
ON p.ClaimID = c.ClaimID
) as x
GROUP BY x.Region
WITH ROLLUP
尽可能避免子选择,如果可以的话。它们的性能不是很好,但当然有时你无法避免
表结构/关系是执行此查询困难的根本原因。在查看了结构之后,我发现您正在复制数据(这是一个“否”),并且在将所有细节拉入一个漂亮的查询中时遇到了问题
我看到的问题领域(以及一些友好的建议)
SELECT e.Region, COUNT(c.SubID) TotalClaims, COUNT(p.[returned date]) UnpaidClaims, COUNT(c.SubID)-COUNT(p.[returned date]) PaidClaims
FROM
Claims c
INNER JOIN enrollment e ON c.SubID = e.SubID
INNER JOIN phoneship p ON p.ClaimID = c.ClaimID
GROUP BY e.Region
您已经包含了用于创建数据库的脚本,但没有包含用于获取所需值的脚本。您尝试的查询是什么?最好用它编辑您的问题,而不是将查询粘贴到评论中(我在前两次为您这样做了)。我知道这并不能回答您的问题,但我想马上告诉您避免在列名中使用空格。这可能会带来麻烦。有些人使用下划线,但我更喜欢驼峰式表示法——例如[Shipping Number]可以是ShippingNumber,在编写查询时更容易键入,您的开发人员(如果您有)也不会想杀了您:DSorry我不想再唠叨了,但只是另一个建议——不要使用DateTime,按照MS的建议使用DateTime2:即使在StackOverFlow@dyslexicanaboko上,为什么CamelCasers会大写第一个字母?他们不应该资本化吗?不是这样吗?