【问题标题】:Creating effective query with multiple tables使用多个表创建有效查询
【发布时间】:2013-02-10 05:40:33
【问题描述】:

我正在尝试查询网站搜索。我需要对这个查询做的是我想根据搜索关键字(导师、机构、学科、城市)选择四个主要列。键入关键字时,查询必须检查这四个表,并且需要在这四个类别下显示搜索结果。显示搜索结果时,我需要添加一些值以生成有意义的搜索结果。例如:考虑在导师类别下显示导师作为搜索结果,我需要显示他/她的姓名、城市、个人资料图片等。

它是这样的。

**Tutors** 
  tutor's name
  city
  profile image
**institutes** 
  institute's name
  city
  profile image 
**subjects**
  subject name
  category name which belong this subject
**cities** 
  city name
  district name which city belong etc... 

我试过这样的

$q = "SELECT keyword, col, city_name, image_name, tutor_code 
        FROM (
            SELECT tutor_name AS keyword, 'Tutors' AS col, IFNULL(c1.city_name, '') city_name, IFNULL(ti.image_name, '') image_name, tutor_code FROM tutors AS t
            LEFT JOIN address a ON t.address_id = a.address_id
            LEFT JOIN city c1 ON a.city_id = c1.city_id 
            LEFT JOIN tutor_images ti ON t.tutor_id = ti.tutor_id AND ti.image_type = 'profile'
            UNION
            SELECT subject_name AS keyword, 'Subject' AS col, '' city_name, '' image_name, '' tutor_code FROM subjects 
            UNION
            SELECT city_name AS keyword, 'City' AS col, '' city_name, '' image_name, '' tutor_code FROM city
            UNION
            SELECT institute_name AS keyword, 'Institute' AS col, '' city_name, '' image_name, '' tutor_code FROM institutes AS i
            LEFT JOIN address a ON i.address_id = a.address_id
            LEFT JOIN city c2 ON a.city_id = c2.city_id 
            LEFT JOIN institute_images ii ON i.institute_id = ii.institute_id AND ii.image_type = 'profile'             
        ) s
      WHERE keyword LIKE '%$queryString%' 
      LIMIT 10";

此查询工作大约 50%,但无法 100% 工作。问题是在机构类别下不显示城市名称和头像,在城市和学科字段下无法显示地区名称和类别名称。而且我想这种查询是无效的,是否浪费时间和资源?

谢谢。

【问题讨论】:

  • 你能用样本数据sqlfiddle这个吗?
  • 我可以在没有 sqlfiddle 的情况下获得解决方案吗?这是一项艰苦的工作,我必须处理更多的表。

标签: mysql sql select union


【解决方案1】:

UNION 尝试将所有SELECT 查询的结果放入一个包含一组列名/数据类型的大表中。因此,所有SELECT 语句的列数和每列的数据类型必须匹配。您已经在使用关键字,这是一种区分类型的有用策略。我认为您可以在正确的列中选择额外的数据来完成这项工作。

我认为您应该做的是尝试并衡量性能。然后并行进行单独的数据库调用并获取结果并衡量该性能。我认为它们将与更易于理解和维护的第二种相媲美。

【讨论】:

  • 感谢您的回复。但是你的答案对我来说不是很清楚。所以你能用一个例子来详细说明一下吗?谢谢。
【解决方案2】:

试试这个:

SELECT keyword, col, city_name, image_name, tutor_code, district_name, category_name 
FROM (
    SELECT tutor_name AS keyword, 'Tutors' AS col, IFNULL(c1.city_name, '') city_name,  
             IFNULL(ti.image_name, '') image_name, tutor_code, '' district_name, '' category_name 
    FROM tutors AS t 
    LEFT JOIN address a ON t.address_id = a.address_id 
    LEFT JOIN city c1 ON a.city_id = c1.city_id 
    LEFT JOIN tutor_images ti ON t.tutor_id = ti.tutor_id AND ti.image_type = 'profile' 
    UNION
    SELECT subject_name AS keyword, 'Subject' AS col, '' city_name, '' image_name, '' tutor_code, 
             '' district_name, c.category_name 
    FROM subjects s 
    LEFT JOIN category_subjects cs ON s.subject_id = cs.subject_id 
    LEFT JOIN category c ON cs.category_id = c.category_id 
    UNION
    SELECT city_name AS keyword, 'City' AS col, '' city_name, '' image_name, '' tutor_code, 
             district_name, '' category_name 
    FROM city 
    UNION
    SELECT institute_name AS keyword, 'Institute' AS col, IFNULL(c2.city_name, '') city_name, 
             IFNULL(ii.image_name, '')  image_name, institute_code tutor_code, '' district_name, '' category_name
    FROM institutes AS i 
    LEFT JOIN address a ON i.address_id = a.address_id  
    LEFT JOIN city c2 ON a.city_id = c2.city_id  
    LEFT JOIN institute_images ii ON i.institute_id = ii.institute_id AND ii.image_type = 'profile'             
) s
WHERE keyword LIKE '%$queryString%' 
LIMIT 10

【讨论】:

  • 你好@Saharsh Shah 很高兴再次见到你。等等,我会检查这个
  • 我的 category_name 来自 category 表和 category_subjects 表有哪个主题属于哪个类别..
  • 再次城市名称未选择机构。
  • 不确定。我也为研究所使用相同的地址和城市表。但不是为机构选择城市,而是与导师合作。
  • 现在可以了。在另一种情况下,我可以将查询第一行中的“tutor_code”更改为 member_code
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-06
  • 1970-01-01
相关资源
最近更新 更多