2010-08-26 47 views
0

我有這個疑問:MySQL動態查詢挑戰 - 請幫助!


SELECT 
    userlist.USERID, 
    (case when (sum(CASE WHEN track.OFFER_ID = 221 THEN 1 ELSE 0 END) > 1) then 1 else 0 end) offer_211 

FROM 
userlist 
INNER JOIN track ON userlist.USERID = track.USERID 

group by 
userid 

這是輸出:

有一個用戶表,報價表:

+------------+---------- 
| USERID  | offer_211 | 
+------------+---------- 
| 1657487706 |   0 | 
| 1238439394 |   0 | 
| 1238427171 |   1 | 
| 1248431441 |   0 | 
| 1248464345 |   1 | 

此查詢的目的跟蹤表。跟蹤表包含用戶表中的所有點擊。我想創建一個如上所示的視圖,這會向我顯示所有優惠的用戶點擊次數。如果用戶點擊某個報價,它將在該報價欄下顯示'1',否則顯示'0'。所有記錄都來自軌道表。

這裏是我需要幫助。 我希望能夠動態地創建列從「報價」表,而不是手動specifing他們「offer_211」(見我的查詢)

所以,用戶點擊或未點擊(列)的所有優惠將來自提供該表格。

它應該是這樣的: 「報價_」 + offer.ID

它應該是這樣的:(假設只有2報價與IDS 211報價表,212)

有可以是優惠表中的100個優惠,所以這個視圖應該有相同數量的動態列。

| USERID  | offer_211 | offer_212 | 
+------------+----------+------------- 
| 1657487706 |   0 |   1 | 
| 1238439394 |   0 |   0 | 
| 1238427171 |   1 |   0 | 
| 1248431441 |   0 |   1 | 
| 1248464345 |   1 |   0 | 

曲目表:

+------------+-------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+------------+-------------+------+-----+---------+----------------+ 
| ID   | int(22)  | NO | PRI | NULL | auto_increment | 
| OFFER_ID | int(22)  | YES | MUL | NULL |    | 
| USERID  | int(22)  | YES | MUL | NULL |    | 
+------------+-------------+------+-----+---------+----------------+ 

用戶名單表:

+-------------+--------------+------+-----+---------+-------+ 
| Field  | Type   | Null | Key | Default | Extra | 
+-------------+--------------+------+-----+---------+-------+ 
| USERID  | int(22)  | NO | PRI | 0  |  | 
| EMAIL  | varchar(200) | YES |  | NULL |  | 
| FIRSTNAME | varchar(100) | YES |  | NULL |  | 
| LASTNAME | varchar(100) | YES |  | NULL |  | 

報價表:

+------------------+--------------+------+-----+-------------+----------------+ 
| Field   | Type   | Null | Key | Default  | Extra   | 
+------------------+--------------+------+-----+-------------+----------------+ 
| ID    | int(11)  | NO | PRI | NULL  | auto_increment | 
| NAME    | varchar(100) | YES |  | NULL  |    | 
| DESCRIPTION  | text   | YES |  | NULL  |    | 
| URL    | text   | YES |  | NULL  |    | 

回答

0

你有沒有考慮讓用戶ID的列表,並提供標識,按f排序首先通過用戶ID,然後按優惠ID?這是相同的信息,只是組織方式稍有不同,再加上數據庫執行諸如「select user_id,offer_id from track」之類的查詢要快得多。

+0

我想要做的是從商品表中動態創建這些列(offer_221) - 而不是像我在查詢中那樣手動添加它們。 – ipernix 2010-08-26 07:24:59

1

這種查詢很快就會變得非常混亂。我會建議使用更多的標準查詢來獲取您的數據,然後在您的應用程序中處理這些數據。

但是,如果有一個很好的理由來創建一個動態查詢,這裏有一個方法可以做到這一點—這些只是積木,所以你需要對其進行修改以滿足您的要求:

使用CONCATGROUP_CONCAT建立一個SELECT語句用在prepared statement

SELECT CONCAT(
    'SELECT', 
    GROUP_CONCAT(
     ' SUM(IF(offer_id = ', offer_id, 
     ', 1, 0)) AS offer_', offer_id), 
    ' FROM track;') 
INTO @sql 
FROM (SELECT DISTINCT offer_id FROM track) AS track; 

這裏是上面的命令創建:

SELECT @sql; 

+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| @sql                                            | 
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| SELECT SUM(IF(offer_id = 1, 1, 0)) AS offer_1, SUM(IF(offer_id = 2, 1, 0)) AS offer_2, SUM(IF(offer_id = 3, 1, 0)) AS offer_3, SUM(IF(offer_id = 4, 1, 0)) AS offer_4 FROM track; | 
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 

創建並從動態SQL執行準備的語句:

PREPARE stmt FROM @sql; 
EXECUTE stmt; 

+---------+---------+---------+---------+ 
| offer_1 | offer_2 | offer_3 | offer_4 | 
+---------+---------+---------+---------+ 
|  3 |  2 |  1 |  1 | 
+---------+---------+---------+---------+ 

DEALLOCATE PREPARE stmt; 
+0

你好邁克; 非常感謝您的意見,我認爲我們走在正確的軌道上。不過,當我運行上面的語句「SELECT @sql;」時,我遇到了一些問題它在聲明結尾處截斷,我得到一個錯誤。這裏是我得到的,也是我修改你的查詢,只得到狀態1 – ipernix 2010-08-26 15:34:31

+0

OFFERs請看下面 – ipernix 2010-08-26 15:35:14

+0

@ipernix:我猜你已經達到'@ sql'變量的長度限制。這就是爲什麼它不是一個真正的好方法的原因之一。您將以非常大且繁瑣的查詢結束。我會研究其他獲得同樣結果的方法。 – Mike 2010-08-26 16:59:39

0

麥克,

這裏它返回什麼:見在結束其切斷如何 - 怪異。會是什麼呢?

我也不明白你的評論的最後部分 - 最後一塊;

Create and execute a prepared statement from the dynamic SQL: 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 

+---------+---------+---------+---------+ 
| offer_1 | offer_2 | offer_3 | offer_4 | 
+---------+---------+---------+---------+ 
|  3 |  2 |  1 |  1 | 
+---------+---------+---------+---------+ 

DEALLOCATE PREPARE stmt; 

下面是新的查詢:

SELECT CONCAT(
    'SELECT', 
    GROUP_CONCAT(
     ' SUM(IF(OFFER_ID = ', offer_id, 
     ', 1, 0)) AS offer_', offer_id), 
    ' FROM track;') 
INTO @sql 
FROM (SELECT DISTINCT ID as OFFER_ID from offer where `STATUS`=1) AS track; 

select @sql; 

這裏是輸出:

SELECT SUM(IF(OFFER_ID = 178,1,0))AS offer_178,SUM(IF( AS offer(202,1,0))AS offer_234,SUM(IF(OFFER_ID = 206,1,0))AS offer_206,SUM(IF(OFFER_ID = 213,1,0))AS offer_213,SUM(IF(OFFER_ID = AS(offer(0,0,0))AS offer_229,SUM(IF(OFFER_ID = 220,1,0))AS offer_220, 1,0))AS offer_222,SUM(IF(OFFER_ID = 225,1,0))AS offer_225,SUM(I F(OFFER_ID = 226,1,0))AS offer_226,SUM(IF(OFFER_ID = 257,1,0))AS offer_257,SUM(IF(OFFER_ID = 259,1,0))AS offer_259,SUM(IF (offer_258,0))AS offer_258,SUM(IF(OFFER_ID = 260,1,0))AS offer_260,SUM(IF(OFFER_ID = 228,1,0))AS offer_228,SUM(IF(OFFER_ID = SUM(IF(OFFER_ID = 233,1,0))AS offer_230,SUM(IF(OFFER_ID = 232,1,0))AS offer_232, (offer_id = 1,0))AS offer_239,SUM(IF(OFFER_ID = 240,1,0))AS offer_240,SUM(IF(OFFER_ID = 241,1,0))AS offer_241,SUM(IF(OFFER_ID = 242,1, 0))AS offer_242,SUM(IF(OFFER_ID = 243,1,0))AS offer_243,SUM(IF(OFFE FROM track;