iT邦幫忙

1

SQL雙查詢,詢問語法?

sql

https://ithelp.ithome.com.tw/upload/images/20171214/20104766rEboJ3aFkY.png
害各位傷眼抱歉,為了簡化資料讓先進一目了然,就用EXCEL簡單打了一下

有一交易資料表,欄位跟紀錄筆數爆多,圖中用‧‧‧作表示
我需要下查詢條件讓Cno欄位有出現'手機'的為基準

想找出有買'手機'的交易裏,會順便買其它甚麼配件共多少
查詢結果就是將黃框的部分搜尋出來

我的思維是先where cno='手機' 一次
將shop,bdate,time取出來 (這三個欄位構成消費單號)
再拿消費單號去where整張表一次
不知道此思維是否正確?

SQL的命令該怎下...再請先進們指點,感恩~!

coreychen iT邦新手 5 級 ‧ 2017-12-14 16:19:17 檢舉
交易資料表本身沒有交易單據號碼嗎?
沒有 交易單號是用 店+時間欄位組成的 並沒有自行產生一組
小魚 iT邦研究生 2 級 ‧ 2017-12-14 20:50:04 檢舉
你的欄位怪怪的,電腦要怎麼知道保護貼是屬於手機的套件呢?
應該要有一個大類叫手機或通訊等等之類的,
下面再一個項目手機、保護貼、充電器等等的,
這樣只要篩選那個大類就可以了,這就有點像拍賣網站的架構。

2 個回答

2
一級屠豬士
iT邦新手 3 級 ‧ 2017-12-14 21:42:01
最佳解答
create table ithelp171214 (
  id serial primary key
, shop char(1) not null
, buy_date date not null
, buy_time time not null
, item text not null
);

insert into ithelp171214 (shop, buy_date, buy_time, item) values
('A', date '2017-01-01', time '16:00', '保護貼'),
('A', date '2017-01-01', time '16:00', '手機'),
('A', date '2017-01-01', time '16:00', '充電器'),
('D', date '2017-02-01', time '18:17', '手機'),
('D', date '2017-02-01', time '18:17', 'USB線'),
('A', date '2017-03-01', time '20:21', '刮鬍刀'),
('A', date '2017-03-01', time '20:21', 'USB線');
--
select * 
  from ithelp171214
 order by shop, buy_date, buy_time;

 id | shop |  buy_date  | buy_time |  item  
----+------+------------+----------+--------
  3 | A    | 2017-01-01 | 16:00:00 | 充電器
  1 | A    | 2017-01-01 | 16:00:00 | 保護貼
  2 | A    | 2017-01-01 | 16:00:00 | 手機
  6 | A    | 2017-03-01 | 20:21:00 | 刮鬍刀
  7 | A    | 2017-03-01 | 20:21:00 | USB線
  4 | D    | 2017-02-01 | 18:17:00 | 手機
  5 | D    | 2017-02-01 | 18:17:00 | USB線
(7 筆資料列)

--
select i.*
  from (select shop
             , buy_date
             , buy_time
         from ithelp171214
        where item = '手機'
       ) a
     , ithelp171214 i
 where a.shop = i.shop
   and a.buy_date = i.buy_date
   and a.buy_time = i.buy_time
 order by shop, buy_date, buy_time; 

 id | shop |  buy_date  | buy_time |  item  
----+------+------------+----------+--------
  1 | A    | 2017-01-01 | 16:00:00 | 保護貼
  2 | A    | 2017-01-01 | 16:00:00 | 手機
  3 | A    | 2017-01-01 | 16:00:00 | 充電器
  4 | D    | 2017-02-01 | 18:17:00 | 手機
  5 | D    | 2017-02-01 | 18:17:00 | USB線
(5 筆資料列)

這次的問題其實不難,只是你不太願意寫subquery而已.
本來我是不想回答的.但是想想還是覺得回答一下好了.
資料型態轉換是有成本的.
而且那樣轉換合併,不利於使用index.
這部份就不再多說了.自己多想想囉.

幸運叔祝大家愉快~~~

太感謝了,非常清楚明瞭,也相當符合我要的需求

0
做工仔人!
iT邦高手 1 級 ‧ 2017-12-14 16:29:29

基本上版主的SAMPLE中少了"交易單號"之類的資料.(一家店每天應該不只買一支手機)
就假設SHOP 就是"交易單號"吧 !

SELECT *
FROM TABLE
WHERE SHOP IN (SELECT SHOP FROM TABLE WHERE cno='手機')

觀念很簡單: 先將含有手機的交易單號找出,成一個LIST,再將這個LIST 中所有的交易資料找出來.

請問做工仔人!大大,假設我的單號是多個欄位拼出來的,無法只用1個shop欄位準確定位,那要如何改?

基本上的改法:
WHERE SHOP+CNO IN (SELECT SHOP+CNO DATA FROM TABLE WHERE cno='手機')
欄位相加:最好用字串方式相加.如有數字或日期.請善用 convert 轉為字串後再相加.

我要發表回答

立即登入回答