2011-12-16 65 views
1

我不能完全確定什麼,我期待在這裏,所以道歉,如果這已經涵蓋在這裏,我不知道我需要尋找!一次和循環結果SQL查詢兩個表JSON對象

我有一個名爲 「位置」 表中的MySQL數據庫,看起來有點像這樣

id | name | other parameters 
1 | shop1 | blah 
2 | shop2 | blah 

和客戶的表查詢

id | customer | department 
1 | john  | shop2 
2 | Joe  | shop2 
3 | James | shop1 
4 | Sue  | shop2 

我想查詢此並返回一個JSON對象,看起來像這樣

{"location":"shop1","queryCount":"1"},{"location":"shop2","queryCount":"3"} 

位置表可以隨時添加,顯然客戶查詢將會是,因此都需要動態查詢。

我想這通過一個簡單的SELECT name from locations查詢得到的位置列表,把它變成一個數組,然後通過循環如下:

For i = UBound(listofLocations) To 0 Step -1 
     locations.id = listofLocations(i) 
     locations.queryCount= RESULT OF: "SELECT COUNT(id) as recordCount from queries WHERE department=listofLocations(i)" 
     objectArray.Add(locations) 
    Next 

這工作,但它是低效調用數據庫通過循環,我如何避免這種情況?

感謝

回答

0

的低效是因爲你使用嵌套查詢,
你應該使用LEFT JOIN,你只需要單個查詢

這裏是SQL: -

select l.name, count(*) as recordCount 
from Locations as l 
left join customer as c 
on l.name = c.department 
group by l.id; 

而你的模式不是很優化。
您的顧客的模式應該是

id, customer, location_id <-- using name is redundant, 
          <-- which should represent in ID (location ID) 
0

首先,我要建議您的「部門」現場進行更換。如果您在地點表中更改名稱的拼寫,那麼您的關係會中斷。

相反,使用id從位置表,併成立了一個外鍵引用。


但是這是一個問題。使用當前的結構,這就是我在做SQL ...

SELECT 
    location.name, 
    COUNT(queries.id)  AS count_of_queries 
FROM 
    locations 
LEFT JOIN 
    queries 
    ON queries.department = locations.name 
GROUP BY 
    location.name 

使用LEFT JOIN,你讓每一個位置,即使它沒有查詢保證。

使用COUNT(queries.id)而不是COUNT(*)給出了0是否有查詢表中沒有相關記錄。


然後,您可以通過循環結果集一個查詢,而不是循環多次查詢,並建立您的JSON字符串。

可能在SQL中構建字符串,但這通常被認爲是不好的做法。更好地保持你關於數據的SQL,以及你的php /關於處理和呈現它的任何內容。

0

試試這個:

SELECT T1.name, (SELECT COUNT(*) FROM queries AS T2 WHERE T2.department = T1.name) AS number FROM locations AS T1; 

我同意你的計劃是不妥當的,你應該通過ID號和部門,叫不上名字

0

我認爲你只是在尋找 「GROUP BY」

SELECT 
    department_id as location, 
    COUNT(id) as querycount 
FROM 
    (table of customer queries) 
GROUP BY 
    department_id 

至於數據庫的結構......如果可能的話,我會改變的表位:

Location: 
id | name | other parameters 

Customer: 
id | name | whatever 

table_of_customer_queries: 
id | customer_id | location_id 
1 |  2  |  2 
2 |  4  |  2 
3 |  2  |  1 
4 |  1  |  2 

GROUP BY只會給你那些具有查詢部門的結果。如果你想要所有的部門,前面提到的LEFT JOIN選項是要走的路。

0

首先,如果你Locations表真正存儲Department信息,將其重命名爲這樣。然後,改變Customer.department是一個FK參考Locations.id列(並更名爲department_id),而不是name(少了這麼多得到錯誤的)。這可能會也可能不會給你提升性能;但是,請記住,在數據庫中的數據是不是真的意味着是可讀 - 它的意思是程序可讀。

在這兩種情況下,查詢可以寫成這樣:

SELECT a.name, (SELECT COUNT(b.id) 
       FROM Customer as b 
       WHERE b.department_id = a.id) as count 
FROM Location as a 
0

如果你不改變你的模式,你的答案是通過計數查詢的數量到每個位置條款做一組。

創建表像您一樣的:

create table #locations (id integer, name varchar(20), other text) 
create table #queries (id integer, customer varchar(20), department varchar(20)) 

insert into #locations (id, name, other) values (1, 'shop1', 'blah') 
insert into #locations (id, name, other) values (2, 'shop2', 'blah') 

insert into #queries (id, customer, department) values (1, 'john', 'shop2') 
insert into #queries (id, customer, department) values (2, 'Joe', 'shop2') 
insert into #queries (id, customer, department) values (3, 'James', 'shop1') 
insert into #queries (id, customer, department) values (4, 'Sue', 'shop2') 

查詢數據:

select 
    l.name as location, 
    count(q.id) as queryCount 
from #locations as l 
left join #queries as q on q.department = l.name 
group by l.name 
order by l.name 

結果:

location    queryCount 
-------------------- ----------- 
shop1    1 
shop2    3