创建这些视图可能有更好的方法。我的SQL体验有限,所以这就是我设计它的方式,我希望你们中的一些SQL大师可以指出我更有效的方向。
我在视图中基本上有3个表(有时是4个),这是必要的结构:
Table USER
USER_ID | EMAIL | PASSWORD | CREATED_DATE
(索引:USER_ID)
Table USER_META
ID | USER_ID | NAME | VALUE
(索引:ID,USER_ID,NAME)
Table USER_SCORES
ID | USER_ID | GAME_ID | SCORE | CREATED_DATE
(索引:ID,USER_ID)
所有表都使用第一个ID列作为自动增量主键。
第二个表“USER_META”是我保存所有联系信息和其他misc的地方。主要是first_name,last_name,street,city等。 - 根据用户的不同,这可能是4项或140,这就是为什么我使用这个表而不是在我的USER表中有150列。
对于报告,搜索和编辑,我需要来自USER_META的大约20个值,所以我的视图看起来像这样:
View V_USR_META
select USER_ID,EMAIL,
(select VALUE from USER_META
where NAME = 'FIRST_NAME' and USER_ID = u.USER_ID) as first_name,
(select VALUE from USER_META
where NAME = 'LAST_NAME' and USER_ID = u.USER_ID) as last_name,
(select VALUE from USER_META
where NAME = 'CITY' and USER_ID = u.USER_ID) as city,
(select VALUE from USER_META
where NAME = 'STATE' and USER_ID = u.USER_ID) as state,
(select VALUE from USER_META
where NAME = 'ZIP' and USER_ID = u.USER_ID) as zip,
/* 10 more selects for different meta values here */
(select max(SCORE) from USER_SCORES
where USER_ID = u.USER_ID) as high_score,
(select top (1) CREATED_DATE from USER_SCORES
where USER_ID = u.USER_ID
order by id desc) as last_game
from USER u
这个问题很慢,实际上有更多的子查询,这只是为了说明查询。我还要查询其他一些表来获取misc。有关用户的信息。
我在搜索用户时使用该视图,搜索使用名称或用户ID或电子邮件或得分等。当我在一个地方展示所有数据时,我还使用它来填充用户信息屏幕。
那么 - 有更好的方法来编写视图吗?
答案 0 :(得分:1)
所有相关子查询的替代方法是将max
与case
一起使用:
select u.USER_ID,
u.EMAIL,
max(case when um.name = 'FIRST_NAME' then um.value end) first_name,
max(case when um.name = 'LAST_NAME' then um.value end) last_name
...
from USER u
left join USER_META um
on u.user_id = um.user_id
group by u.user_id, u.email
然后您可以添加user_scores
结果:
select u.USER_ID,
u.EMAIL,
max(case when um.name = 'FIRST_NAME' then um.value end) first_name,
max(case when um.name = 'LAST_NAME' then um.value end) last_name
...,
max(us.score) maxscore,
max(us.created_date) maxcreateddate
from USER u
left join USER_META um
on u.user_id = um.user_id
left join USER_SCORES us
on u.user_id = us.user_id
group by u.user_id, u.email
答案 1 :(得分:0)
WITH Meta AS (
SELECT USER_ID
,FIRST_NAME
,LAST_NAME
,CITY
,STATE
,ZIP
FROM USER_META
PIVOT (
MAX(VALUE) FOR NAME IN (FIRST_NAME, LAST_NAME, CITY, STATE, ZIP)
) AS p
)
,MaxScores AS (
SELECT USER_ID
,MAX(SCORE) AS Score
FROM USER_SCORES
GROUP BY USER_ID
)
,LastGames AS (
SELECT USER_ID
,MAX(CREATED_DATE) AS GameDate
FROM USER_SCORES
GROUP BY USER_ID
)
SELECT USER.USER_ID
,USER.EMAIL
,Meta.FIRST_NAME
,Meta.LAST_NAME
,Meta.CITY
,Meta.STATE
,Meta.ZIP
,MaxScores.Score
,LastGames.GameDate
FROM USER
INNER JOIN Meta
ON USER.USER_ID = Meta.USER_ID
LEFT JOIN MaxScores
ON USER.USER_ID = MaxScores.USER_ID
LEFT JOIN LastGames
ON USER.USER_ID = LastGames.USER_ID