报告:来自多个表的复杂SQL查询

时间:2014-11-23 17:48:53

标签: sql-server-2008

我有以下需要在此查询中使用的表:

我只提及下表中的相关列,以便排序和理解。

- > item [包含列:Item_ID,ItemCode,ItemName等...]

Item_ID   ItemCode      ItemName
---------------------------------------------
1         P_1           Flower Pots
2         P_2           Parkar Pen
3         P_3           xyz
4         P_4           Aero Pace

- > channelstores [包含列:Store_ID,StoreName等...]

Store_ID    StoreName
---------------------------------
1           Amazon UK
2           Amazon US
3           eBay UK
4           eBay US

- > channel_A [with columns:Item_ID,Store_ID等...]

Item_ID   Store_ID
---------------------
1         1
1         2
2         2
3         1

- > channel_B [包含列:Item_ID,Store_ID等...]

Item_ID   Store_ID
-------------------
1         3
1         4
2         3
3         3

表channel_A和channel_B分别从item和channelstores表中将Item_ID和Store_ID作为外键。

现在,问题是:我需要一个可以给我结果的查询:项目表中包含其channelstore,channel_A和channel_B关系的所有项目的列表如下:

Item_ID   ItemCode    Amazon UK    Amazon US   eBay UK    eBay US
---------------------------------------------------------------------
1            P_1             True         True       True       True
2            P_2             False        True       True       False
3            P_3             True         False      True       False
4            P_4             False        False      False      False

我使用了以下查询,但有问题是获取True / False值:

Declare @StoreName as nvarchar(Max)
Declare @StrQuery nvarchar(Max)
set @StoreName=(SELECT  STUFF((SELECT distinct ',' + '['+p1.[storename]+']' 
FROM channelstores p1 FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'') )

set @StrQuery=
'select Item_ID,ProductCode, '+@StoreName+' from 
(select i.Item_ID,i.itemcode as ProductCode,1 as Value,'''' as ChannelStore from item as i 
) as x
pivot
(max(Value)
for ChannelStore in ('+@StoreName+'))p order by ProductCode'
EXEC(@StrQuery)   

感谢。

1 个答案:

答案 0 :(得分:0)

  
    

我只提到下表中的相关列,以便它可以排序和理解。 <<

  

然后我们需要键和约束;这意味着某种DDL。 “item_code”是UPC,EAN还是其他行业标准代码?我们不知道。但是顺序的“item_id”看起来毫无用处;有人不小心把IDENTITY列放在桌子上吗?我们需要那个骨架!

CREATE TABLE Items
(upc CHAR(10) NOT NULL PRIMARY KEY, 
 item_name VARCHAR(25) NOT NULL);

CREATE TABLE Channel_Stores
(store_id CHAR(10) NOT NULL PRIMARY KEY, 
 store_name  VARCHAR(25) NOT NULL);

因为你很粗鲁,我们还要猜测多余的表格。

- 错了!

CREATE TABLE Channel_A 
(upc CHAR(10) NOT NULL PRIMARY KEY
   REFERENCES Items(upc),
 store_id VARCHAR(25) NOT NULL
   REFERENCES Channel_Stores(store_id),
 PRIMARY KEY (upc, store_id));

- 错了!

CREATE TABLE Channel_B
(upc CHAR(10) NOT NULL PRIMARY KEY
   REFERENCES Items(upc),
 store_id VARCHAR(25) NOT NULL
   REFERENCES Channel_Stores(store_id),
 PRIMARY KEY (upc, store_id));
  
    

表Channel_A和Channel_B分别将来自Items和Channel_Stores表的upc和store_id作为外键。 <<

  

此设计错误称为“属性拆分”,我们不这样做。你会在架构中使用“male_Personnel”和“Female_Personnel”表吗?没有!在有效的ISO-11179模式中它将是“Personnel”。

你不知道规范化的桌子是什么!这就是您在动态SQL中修复错误的原因。此表包含您需要传递到表示层的所有信息。

CREATE TABLE Channels 
(upc CHAR(10) NOT NULL PRIMARY KEY
   REFERENCES Items(upc),
 store_id VARCHAR(25) NOT NULL
   REFERENCES Channel_Stores(store_id),
 channel_name CHAR(1) NOT NULL
   CHECK (Channel_name IN ('A', 'B')),
 PRIMARY KEY (upc, store_id, Channel_name));

如此简单!便携!

  
    

现在,问题是:我需要一个可以给我结果的查询:具有Channel_Stores,Channel_A和Channel_B关系的Items中所有项目的列表如下:<<

  

您可以,但SQL程序员可以使用报表工具执行此操作。这里什么都不是SQL。

我们不在RDBMS中使用汇编语言位标志。

我们避免使用专有代码,以便我们可以将程序移植到下一个版本或另一个SQL。

我们不会在查询或架构中混用XML或其他编程语言。它破坏了性能并使代码成为一个婊子。

SELECT DISTINCT表明架构和查询中的设计缺陷导致结果出现冗余。

我们不在SQL中使用局部变量;这是一种声明性语言。

唯一让这种情况变得更糟的事情就是动态SQL违反 First Normal Form ,然后你就这样做了!