SQL查询一次两个表,循环结果作为JSON对象

时间:2011-12-16 16:33:07

标签: mysql sql vb.net

我不确定我在这里寻找什么,所以如果已经在这里讨论了这件事我很抱歉,我不确定我需要搜索什么!

我有一个MySQL数据库,其中包含一个名为“Locations”的表,看起来有点像这样

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

这样可行,但通过循环调用数据库效率很低,我该如何避免这种情况?

由于

6 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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 /其他内容。

答案 2 :(得分:0)

试试这个:

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

我同意您的方案不合适,您应该通过ID引用部门,而不是名称

答案 3 :(得分: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选项是可行的方法。

答案 4 :(得分:0)

首先,如果您的Locations表确实存储了Department信息,请将其重命名。然后,将Customer.department更改为Locations.id列的fk引用(并重命名为department_id),而不是name(更不用说出错)。这可能会也可能不会给你带来性能提升;但是,请记住,数据库中的数据实际上不是 human 可读 - 它意味着 program 可读。

在任何一种情况下,查询都可以这样写:

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

答案 5 :(得分: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