2011-12-16 8 views
1

私はここで何を探しているのかよくわからないので、ここではすでに説明していますが、謝る必要があります。SQLを一度に2つのテーブルにクエリし、結果をJSONオブジェクトとしてループ

私は少しこの

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 

など

に照会し、 "場所" と呼ばれるテーブルを持つMySQLデータベースを持っています

これを照会して、このような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を使用し、外部キー参照を設定します。


しかし、それはさておきです。あなたの現在の構造を使用して、これは私はあなたがそれのためのクエリがない場合でも、すべての場所を取得性を保証しLEFT JOINを使用して... 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 

を行いたいものです。

COUNT(*)の代わりにCOUNT(queries.id)を使用すると、クエリテーブルに関連するレコードがない場合は0が返されます。


それからできる1つのクエリの結果セットではなく、複数のクエリをループをループし、あなたの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; 

は、私はあなたの仕組みが適切でないことに同意し、あなたがいない名前

0

私はあなただけ

"BY GROUP" を探しているのだと思うことで、Idで部署を参照する必要がありますデータベースの構造については
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.departmentLocations.id列へのfk参照に変更し、nameではなく、department_idという名前に変更してください(間違ったことはあまりありません)。これはパフォーマンスの向上をもたらすかもしれません。ただし、データベース内のデータは実際には人の人間の読み込みが意図されていないことを覚えておいてください。プログラムが読めるようになっています。いずれの場合も

、クエリはそのように書くことができます。

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

あなたのスキーマを変更しない場合は、あなたの答えは、それぞれの場所にクエリの数をカウントgroup by句を行うことです。

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 
あなたのようなテーブルを作成する

関連する問題