三表联查并排除重复项的问题

gxbsdzf 2014-09-06 09:36:23
从以下三个表检索数据:
品名表T1:
ID 品名 规格 功能 厂家
1 品名1 规格1 功能1 厂家1
2 品名2 规格2 功能2 厂家2
3 品名3 规格3 功能3 厂家3

销售表T2:
ID 品名ID 数量 价格 销售情况
1 品名ID1 1 价格1 销售情况1
2 品名ID2 3 价格2 销售情况2
3 品名ID3 1 价格3 销售情况3

编号表T3:
ID 销售表ID 编号
1 1 1
2 2 2
3 2 3
4 2 4
5 3 5

希望得到这样的结果(按编号排序,但品名不重复):
品名 数量 编号 功能 ……
品名1 1 1 功能1
品名2 3 2~4 功能2
品名3 1 5 功能3

问题:如果不按编号排序,比较容易实现,但我的要求是要按编号排序,结果得到了有重复品名的结果:
品名 数量 编号 功能 ……
品名1 1 1 功能1
品名2 3 2 功能2
品名2 3 3 功能2
品名2 3 4 功能2
品名3 1 5 功能3

我现在的句子是:
select t1.品名,t2.数量,(select cast(min(t3.编号) as varchar)+'~'+cast(max(t3.编号)) as varchar as bh from t3 where t3.销售表id=t2.id) as 编号,t1.功能 from t2 inner join t1 on t1.ID=t2.品名id inner join t3 on t3.销售表id=t2.id where …………

若加l了 order by t3.编号 ,就有重复的品名。

希望各位提供更好的SQL句子(不考虑存储过程)。谢谢!
...全文
473 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
gxbsdzf 2014-09-20
  • 打赏
  • 举报
回复
测试通过。感谢19楼Tiger_Zhao,句子很精妙。也感谢alimake。 结帖。
gxbsdzf 2014-09-12
  • 打赏
  • 举报
回复
今天尝试了另一个办法:在销售表T2中新增一个int字段“首编号”,仅保存其编号的起点值,即在生成1至多个编号的同时将首个编号存于“首编号”字段中,专门用于排序。这样算是变通解决了问题。
gxbsdzf 2014-09-12
  • 打赏
  • 举报
回复
表2里面的编号并不按照品名递增,编号还可以允许被手工修改成其他不重复的编号值。 19楼Tiger_Zhao的结果正确,我就是想要这样的结果集。待我抽空测试一下。
Tiger_Zhao 2014-09-12
  • 打赏
  • 举报
回复
select t1.品名,
t2.数量,
case when s3.min编号=s3.max编号 then
cast(s3.min编号 as varchar)
else
cast(s3.min编号 as varchar)+'~'+cast(s3.max编号 as varchar)
end as 编号
,t1.功能
from t2
inner join t1 on t1.ID=t2.品名id
inner join ( select 销售表id,
min(编号) min编号,
max(编号) max编号
from t3
group by 销售表id
) s3
on s3.销售表id=t2.id
order by s3.min编号 --非返回的字段也可以用来排序

品名         数量 编号                      功能
----- ----------- ------------------------- -----
品名1 1 1 功能1
品名3 1 5 功能3
品名2 3 102~104 功能2
xiaodongni 2014-09-12
  • 打赏
  • 举报
回复
在表2里面如果编号是按照品名递增的。那么直接ORDER BY 品名也是可以的
xiaodongni 2014-09-08
  • 打赏
  • 举报
回复

 t3(id,销售表id,编号) as 
  (select '1','1','1'union all
   select '2','2','2'union all
   select '3','2','3'union all
   select '4','2','99'union all
   select '5','3','100')
品名 数量 编号 功能 ----- ---- -------------------------------------------------------------- ----- 品名1 1 1 功能1 品名3 1 100 功能3 品名2 3 2~99 功能2 显示的顺序是这样 不对是吧。,我觉得要是你的表2保证编号是按照品名递增的 直接ORDER by 品名。
xiaodongni 2014-09-08
  • 打赏
  • 举报
回复
你不要光用理论啊。自己举个例子。我的代码算出来是啥格式。但是你需要的是啥格式。 你这个对于 1 1 1 2 2 2 3 2 3 4 2 4 5 3 5 对于这个 表。相同ID 的编号是不是应该都是连续的。不出出现。ID=1的编号是1,3,5 而ID=2的编号是2,4,6
gxbsdzf 2014-09-07
  • 打赏
  • 举报
回复
可能是我没表述清楚。抱歉。 我是希望按编号表中的“编号”字段(int型)来排序,但又能在结果集中用一个字段概述其首尾号,避免逐条罗列编号。 结果集中的编号字段已转化为“***~****”这样的字符串,如果按其来排序,肯定不是按数值大小规律排序,而是按字符的规律排序。按这个方式排序我是试过了的,得不到我要的结果。所有向大家求援来了。 我想要的结果,就是结果集的顺序是按编号数值的大小排序,但又不出现重复项。这应该是表述清楚的吧。 编号表中的编号个数对应销售表中的数量,目前有6万多个,从1到61301,没有重复。但其基本格式就是上面示例的样子。 你句式中用到case来判断某个商品有单个编号时的取值很巧,我已借鉴。谢谢。这点之前没有留意,导致会出现“1~1”这样的情形。
gxbsdzf 2014-09-07
  • 打赏
  • 举报
回复
补充:在实例中我在编号表T3的编号字段上建立了聚集索引。
gxbsdzf 2014-09-07
  • 打赏
  • 举报
回复
品名2的数量是3,应该只有3个编号,不会有2~103个编号这么多。应该是2、3、4,或101、102、103。你试一下将品名2的编号改为101、102、103,再按你的方法检索,品名2这一行的编号栏会显示“101~103”,但这实际上是不对的,品名3的编号是5,明显比101、102、103小,不应该排到他们后面。
xiaodongni 2014-09-07
  • 打赏
  • 举报
回复
 select t1.品名,t2.数量,
   (select   case when max(convert (int,t3.编号))=min(convert (int,t3.编号))
   then max (t3.编号)
   else 
   cast(min(convert(int,t3.编号)) as varchar)
   +'~'+cast(max(convert(int,t3.编号)) as varchar) end as bh from t3
    where t3.销售表id=t2.id) as 编号,t1.功能 from t2 
    inner join t1 on t1.ID=t2.id
    order by 编号
品名    数量   编号                                                             功能
----- ---- -------------------------------------------------------------- -----
品名1   1    1                                                              功能1
品名2   3    2~103                                                         功能2
品名3   1    5                                                              功能3

(3 行受影响)

这个不行吗
gxbsdzf 2014-09-07
  • 打赏
  • 举报
回复
继续求解。麻烦大家再想想办法。
xiaodongni 2014-09-07
  • 打赏
  • 举报
回复
不要让我改成101,102,试试。你自己改啊。然后把结果贴出来 对于如果编号是101,102,103,你需要啥结果
xiaodongni 2014-09-07
  • 打赏
  • 举报
回复
引用 11 楼 gxbsdzf 的回复:
补充:在实例中我在编号表T3的编号字段上建立了聚集索引。
看你回复有2个问题。 1 品名2的数量是3,应该只有3个编号,不会有2~103个编号这么多。 如果编号就是2,4,103 你怎么显示。 2 排序问题。你安装INT 来排序是吧。但是我问下如果是2-103, 还有一个品名只有1个是4 那应该排在前面还是后面。
gxbsdzf 2014-09-06
  • 打赏
  • 举报
回复
这是不对的。
gxbsdzf 2014-09-06
  • 打赏
  • 举报
回复
上面几条记录仅用于试验,现实是很多编号,某种商品有2件,就会有两个编号,某种商品有12件就会有12个编号,这些编号是递增的,且是唯一的,是数值型,但列出清单时,要求商品的编号栏缩减为该商品的起始编号至终止编号来显示,即编号栏的值已变成了字符型,如果以其排序,结果就不是按数值从小到大排序,而是1开头的排完才到2开头、3开头的,等等,比如从1到101、111、1111,才到2、200、201、2222,……,这是的对的。难点之一也在这里。
xiaodongni 2014-09-06
  • 打赏
  • 举报
回复
品名    数量   编号                                                             功能
----- ---- -------------------------------------------------------------- -----
品名1   1    1                                                              功能1
品名2   3    103~4                                                   功能2
品名3   1    5                                                              功能3

(3 行受影响)
改成103是这个结果。你对于这情况要显示成 2~103吗
 select t1.品名,t2.数量,
   (select   case when max(convert (int,t3.编号))=min(convert (int,t3.编号))
   then max (t3.编号)
   else 
   cast(min(convert(int,t3.编号)) as varchar)
   +'~'+cast(max(convert(int,t3.编号)) as varchar) end as bh from t3
    where t3.销售表id=t2.id) as 编号,t1.功能 from t2 
    inner join t1 on t1.ID=t2.id
    order by 编号
   
xiaodongni 2014-09-06
  • 打赏
  • 举报
回复
with  t1(ID,品名,规格,功能,厂家) as 
(select '1','品名1','规格1','功能1','厂家1' union all
 select '2','品名2','规格2','功能2','厂家2' union all
 select '3','品名3','规格3','功能3','厂家3') ,
 t2(id,品名id,数量,价格,销售情况) as 
 (select '1','品名ID1','1','价格1','销售情况1' union all
  select '2','品名ID2','3','价格2','销售情况2' union all
  select '3','品名ID3','1','价格3','销售情况3' ),
  t3(id,销售表id,编号) as 
  (select '1','1','1'union all
   select '2','2','2'union all
   select '3','2','3'union all
   select '4','2','4'union all
   select '5','3','5')
   select t1.品名,t2.数量,
   (select   case when max(t3.编号)=min(t3.编号) 
   then max(t3.编号)
   else 
   cast(min(t3.编号) as varchar)
   +'~'+cast(max(t3.编号) as varchar) end as bh from t3
    where t3.销售表id=t2.id) as 编号,t1.功能 from t2 
    inner join t1 on t1.ID=t2.id
    order by 编号
   

  
 
测试代码
xiaodongni 2014-09-06
  • 打赏
  • 举报
回复
品名    数量   编号                                                             功能
----- ---- -------------------------------------------------------------- -----
品名1   1    1                                                              功能1
品名2   3    2~4                                                            功能2
品名3   1    5                                                              功能3

(3 行受影响)
select t1.品名,t2.数量, (select case when max(t3.编号)=min(t3.编号) then max(t3.编号) else cast(min(t3.编号) as varchar) +'~'+cast(max(t3.编号) as varchar) end as bh from t3 where t3.销售表id=t2.id) as 编号,t1.功能 from t2 inner join t1 on t1.ID=t2.id order by 编号 有问题吗
gxbsdzf 2014-09-06
  • 打赏
  • 举报
回复
试着把编号表T3第3个记录的编号“5”改为“10”或“123”,就会发生这一问题。
加载更多回复(1)

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧