我想在我的sql查询中创建自定义顺序,只需更改一行位置。
这是我目前的sql结果 -
Age Category Female Male
-------------------------------
30-39 2772 3193
40-49 1587 2246
50-65 990 3718
Over 65 176 3487
Under 30 1359 1500
我希望他们这样排序,并且在30岁以下。在顶部 -
Age Category Female Male
-------------------------------
Under 30 1359 1500
30-39 2772 3193
40-49 1587 2246
50-65 990 3718
Over 65 176 3487
这是我的代码 -
SELECT DISTINCT
CASE
WHEN datediff(YYYY,birth_date,getdate()) <= 30 THEN 'Under 30'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 30 AND 39 THEN '30-39'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 40 AND 49 THEN '40-49'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 50 AND 65 THEN '50-65'
WHEN datediff(YYYY,birth_date,getdate()) >= 65 THEN 'Over 65'
END as 'Age Category',
CASE
WHEN datediff(YYYY,birth_date,getdate()) <= 30 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) <= 30 and gender ='f' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 30 AND 39 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 30 AND 39 and gender ='f' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 40 AND 49 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 40 AND 49 and gender ='f' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 50 AND 65 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 50 AND 64 and gender ='f' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) >= 65 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) >= 65 and gender ='f' and status ='a' and member_type ='mm')
END as 'Female',
CASE
WHEN datediff(YYYY,birth_date,getdate()) <= 30 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) <= 30 and gender ='m' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 30 AND 39 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 30 AND 39 and gender ='m' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 40 AND 49 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 40 AND 49 and gender ='m' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 50 AND 65 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 50 AND 64 and gender ='m' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) >= 65 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) >= 65 and gender ='m' and status ='a' and member_type ='mm')
END as 'Male'
FROM NAME N1
WHERE [STATUS] ='A' AND
MEMBER_TYPE IN ('MM') AND
(
CASE
WHEN datediff(YYYY,birth_date,getdate()) <= 30 THEN 'Under 30'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 30 AND 39 THEN '30-39'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 40 AND 49 THEN '40-49'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 50 AND 65 THEN '50-65'
WHEN datediff(YYYY,birth_date,getdate()) >= 65 THEN 'Over 65'
END
) IS NOT NULL
group by datediff(YYYY,birth_date,getdate()), member_type
非常感谢
答案 0 :(得分:2)
添加手动计算的SortOrder列,然后按此顺序和[年龄类别]
进行排序SELECT DISTINCT
CASE
WHEN datediff(YYYY,birth_date,getdate()) <= 30 THEN 'Under 30'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 30 AND 39 THEN '30-39'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 40 AND 49 THEN '40-49'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 50 AND 65 THEN '50-65'
WHEN datediff(YYYY,birth_date,getdate()) >= 65 THEN 'Over 65'
END as 'Age Category',
CASE
WHEN datediff(YYYY,birth_date,getdate()) <= 30 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) <= 30 and gender ='f' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 30 AND 39 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 30 AND 39 and gender ='f' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 40 AND 49 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 40 AND 49 and gender ='f' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 50 AND 65 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 50 AND 64 and gender ='f' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) >= 65 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) >= 65 and gender ='f' and status ='a' and member_type ='mm')
END as 'Female',
CASE
WHEN datediff(YYYY,birth_date,getdate()) <= 30 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) <= 30 and gender ='m' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 30 AND 39 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 30 AND 39 and gender ='m' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 40 AND 49 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 40 AND 49 and gender ='m' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 50 AND 65 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate())BETWEEN 50 AND 64 and gender ='m' and status ='a' and member_type ='mm')
WHEN datediff(YYYY,birth_date,getdate()) >= 65 THEN (select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) >= 65 and gender ='m' and status ='a' and member_type ='mm')
END as 'Male'
-- Newly inserted code starts
CASE
WHEN datediff(YYYY,birth_date,getdate()) <= 30 THEN 1
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 30 AND 65 THEN 3
WHEN datediff(YYYY,birth_date,getdate()) >= 65 THEN 2
END as 'SortOrder',
-- Newly Inserted Code Ends
FROM NAME N1
WHERE [STATUS] ='A' AND
MEMBER_TYPE IN ('MM') AND
(
CASE
WHEN datediff(YYYY,birth_date,getdate()) <= 30 THEN 'Under 30'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 30 AND 39 THEN '30-39'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 40 AND 49 THEN '40-49'
WHEN datediff(YYYY,birth_date,getdate()) BETWEEN 50 AND 65 THEN '50-65'
WHEN datediff(YYYY,birth_date,getdate()) >= 65 THEN 'Over 65'
END
) IS NOT NULL
group by datediff(YYYY,birth_date,getdate()), member_type
-- newly inserted code
ORDER BY SortOrder, [Age Category]
答案 1 :(得分:2)
仅仅通过?添加订单就足够了 按日期订购(YYYY,birth_date,getdate())
否则,也许您也可以将年龄类别更改为&#34; 30和&#34;和&#34; 65及以上&#34;
编辑此查询可能更容易/更少重复。顺便说一句,BETWEEN子句是包容性的,所以你应该使用&lt; 30而不是&lt; = 30(并且&gt; 65而不是&gt; = 65)以确保这些年龄不被计算两次。
SELECT 'Under 30' AS 'Age Category',
(select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) < 30 and gender ='f' and status ='a' and member_type ='mm') AS 'Female',
(select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) < 30 and gender ='m' and status ='a' and member_type ='mm') AS 'Male'
UNION ALL
SELECT '30-39',
(select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) BETWEEN 30 AND 39 and gender ='f' and status ='a' and member_type ='mm')
(select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) BETWEEN 30 AND 39 and gender ='m' and status ='a' and member_type ='mm')
UNION ALL
SELECT '40-49',
(select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) BETWEEN 40 AND 49 and gender ='f' and status ='a' and member_type ='mm')
(select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) BETWEEN 40 AND 49 and gender ='m' and status ='a' and member_type ='mm')
UNION ALL
SELECT '50-65',
(select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) BETWEEN 50 AND 65 and gender ='f' and status ='a' and member_type ='mm')
(select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) BETWEEN 50 AND 65 and gender ='m' and status ='a' and member_type ='mm')
UNION ALL
SELECT 'Over 65',
(select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) > 65 and gender ='f' and status ='a' and member_type ='mm')
(select count(*) from name n1 where datediff(YYYY,n1.birth_date,getdate()) > 65 and gender ='m' and status ='a' and member_type ='mm')
答案 2 :(得分:1)
如果您创建一个要加入的表,这将变得更加容易。
CREATE TABLE dim_age_band (
id INT,
title VARCHAR(32),
ordinal INT,
bound_lower INT,
bound_upper INT
)
INSERT INTO dim_age_band SELECT 1, 'Under 30', 1, 0, 30;
INSERT INTO dim_age_band SELECT 2, '30-39', 2, 30, 40;
INSERT INTO dim_age_band SELECT 3, '40-49', 3, 40, 50;
INSERT INTO dim_age_band SELECT 4, '50-65', 4, 50, 66;
INSERT INTO dim_age_band SELECT 5, 'Over 65', 5, 66, 1000;
SELECT
MAX([dim_age_band].[name] ) AS age_band_name,
SUM(CASE WHEN [name].[gender] = 'f' THEN 1 ELSE 0 END) AS female,
SUM(CASE WHEN [name].[gender] = 'm' THEN 1 ELSE 0 END) AS male
FROM
dim_age_band
LEFT JOIN
name
ON [name].[birth_date] <= DATEADD(YYYY, GetDate(), [dim_age_band].[bound_lower])
AND [name].[birth_date] > DATEADD(YYYY, GetDate(), [dim_age_band].[bound_Upper])
AND [name].[STATUS] = 'A'
AND [name].MEMBER_TYPE IN ('MM')
GROUP BY
[dim_age_band].[id]
ORDER BY
MAX([dim_age_band].[ordinal])
;
编辑:
请注意,我在[birth_date]
字段上使用DATEDIFF()也 。相反,我在今天的日期和年龄段边界上运行该计算。这意味着可以使用索引通过[name]
搜索[birth_date]
表;如果存在这样的指数。
编辑:
CTE版本......
WITH
dim_age_band (name, ordinal, bound_lower, bound_upper)
AS
(
SELECT 'Under 30', 1, 0, 30
UNION ALL SELECT '30-39', 2, 30, 40
UNION ALL SELECT '40-49', 3, 40, 50
UNION ALL SELECT '50-65', 4, 50, 66
UNION ALL SELECT 'Over 65', 5, 66, 1000
)
SELECT
MAX([dim_age_band].[name] ) AS age_band_name,
SUM(CASE WHEN [name].[gender] = 'f' THEN 1 ELSE 0 END) AS female,
SUM(CASE WHEN [name].[gender] = 'm' THEN 1 ELSE 0 END) AS male
FROM
dim_age_band
LEFT JOIN
name
ON [name].[birth_date] <= DATEADD(YYYY, GetDate(), [dim_age_band].[bound_lower])
AND [name].[birth_date] > DATEADD(YYYY, GetDate(), [dim_age_band].[bound_Upper])
AND [name].[STATUS] = 'A'
AND [name].MEMBER_TYPE IN ('MM')
GROUP BY
[dim_age_band].[id]
ORDER BY
MAX([dim_age_band].[ordinal])
;
内联视图版本:
SELECT
MAX([dim_age_band].[name] ) AS age_band_name,
SUM(CASE WHEN [name].[gender] = 'f' THEN 1 ELSE 0 END) AS female,
SUM(CASE WHEN [name].[gender] = 'm' THEN 1 ELSE 0 END) AS male
FROM
(
SELECT 'Under 30' AS name, 1 AS ordinal, 0 AS bound_lower, 30 AS bound_upper
UNION ALL SELECT '30-39' AS name, 2 AS ordinal, 30 AS bound_lower, 40 AS bound_upper
UNION ALL SELECT '40-49' AS name, 3 AS ordinal, 40 AS bound_lower, 50 AS bound_upper
UNION ALL SELECT '50-65' AS name, 4 AS ordinal, 50 AS bound_lower, 66 AS bound_upper
UNION ALL SELECT 'Over 65' AS name, 5 AS ordinal, 66 AS bound_lower, 1000 AS bound_upper
)
AS dim_age_band
LEFT JOIN
name
ON [name].[birth_date] <= DATEADD(YYYY, GetDate(), [dim_age_band].[bound_lower])
AND [name].[birth_date] > DATEADD(YYYY, GetDate(), [dim_age_band].[bound_Upper])
AND [name].[STATUS] = 'A'
AND [name].MEMBER_TYPE IN ('MM')
GROUP BY
[dim_age_band].[id]
ORDER BY
MAX([dim_age_band].[ordinal])
;