Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何避免查询时的笛卡尔积?_Mysql_Sql_Cartesian - Fatal编程技术网

Mysql 如何避免查询时的笛卡尔积?

Mysql 如何避免查询时的笛卡尔积?,mysql,sql,cartesian,Mysql,Sql,Cartesian,我正在构建一个分类广告的web应用程序(这是我第一个专业的PHP应用程序)。我有一个表和广告和其他的图像为每个广告。每个广告可以有多达4个图像。当我只为每个广告添加一个图像时,一切都很好。现在,当我为每个广告添加多个图像时,广告会在列表中重复(每个图像重复一次)。下面是我正在使用的SQL: SELECT sun_classified_ads.ad_id, sun_classified_ads.insertion_datetime, sun_classified_ads.title,

我正在构建一个分类广告的web应用程序(这是我第一个专业的PHP应用程序)。我有一个表和广告和其他的图像为每个广告。每个广告可以有多达4个图像。当我只为每个广告添加一个图像时,一切都很好。现在,当我为每个广告添加多个图像时,广告会在列表中重复(每个图像重复一次)。下面是我正在使用的SQL:

SELECT 
sun_classified_ads.ad_id, 
sun_classified_ads.insertion_datetime, 
sun_classified_ads.title,                
sun_classified_ads.description, 
sun_classified_ads.maker, 
sun_classified_ads.model, 
sun_classified_ads.location, 
sun_classified_ads.price, 
sun_classified_ads_images.filename_mini, 
sun_classified_ads_images.size_attr_mini, 
sun_classified_ads_images.description AS image_description
FROM sun_classified_ads
INNER JOIN sun_classified_ads_images ON sun_classified_ads.ad_id =       sun_classified_ads_images.ad_id

我该怎么做?它只使用sun_classified_ads_images表中该广告的第一张图片?

简短的回答是“你不能”。您编写的查询将返回所有匹配数据的所有行。每个图像的数据匹配一次。你需要做两个查询——一个是获取所有的广告,另一个是在页面上的广告中查询所有的图片。这是最直接的方法。

您没有说明表是否有
datetime
,以及何时添加
图像。如果是这样,那么您可以更改下面的查询以返回每个广告的
min()
日期

如果没有,那么您可能仍然可以使用以下选项:

SELECT 
  a.ad_id, 
  a.insertion_datetime, 
  a.title,                
  a.description, 
  a.maker, 
  a.model, 
  a.location, 
  a.price, 
  i.filename_mini, 
  i.size_attr_mini, 
  i.description AS image_description
FROM sun_classified_ads a
INNER JOIN
(
  select min(ad_id) Min_Ad_id, ad_id
  from sun_classified_ads_images i
  group by ad_id
) i
  ON a.ad_id = i.ad_id
INNER JOIN sun_classified_ads_images i2
  ON a.ad_id = i2.ad_id
  and i.Min_Ad_id = i2.ad_id
SELECT 
sun_classified_ads.ad_id, 
sun_classified_ads.insertion_datetime, 
sun_classified_ads.title,                
sun_classified_ads.description, 
sun_classified_ads.maker, 
sun_classified_ads.model, 
sun_classified_ads.location, 
sun_classified_ads.price, 
sun_classified_ads_images.filename_mini, 
sun_classified_ads_images.size_attr_mini, 
sun_classified_ads_images.description AS image_description
FROM sun_classified_ads
INNER JOIN sun_classified_ads_images ON sun_classified_ads.ad_id =       sun_classified_ads_images.ad_id
group by sun_classified_ads.ad_id
如果图像表中有
datetime
,则可以使用:

INNER JOIN
(
  select min(ad_date) Min_Ad_Date, ad_id
  from sun_classified_ads_images i
  group by ad_id
) i
  ON a.ad_id = i.ad_id
INNER JOIN sun_classified_ads_images i2
  ON a.ad_id = i2.ad_id
  and i.Min_Ad_Date = i2.ad_date
MySQL有一个叫做隐藏列的“特性”。您可以使用以下方法为每个广告获取一张图像:

SELECT 
  a.ad_id, 
  a.insertion_datetime, 
  a.title,                
  a.description, 
  a.maker, 
  a.model, 
  a.location, 
  a.price, 
  i.filename_mini, 
  i.size_attr_mini, 
  i.description AS image_description
FROM sun_classified_ads a
INNER JOIN
(
  select min(ad_id) Min_Ad_id, ad_id
  from sun_classified_ads_images i
  group by ad_id
) i
  ON a.ad_id = i.ad_id
INNER JOIN sun_classified_ads_images i2
  ON a.ad_id = i2.ad_id
  and i.Min_Ad_id = i2.ad_id
SELECT 
sun_classified_ads.ad_id, 
sun_classified_ads.insertion_datetime, 
sun_classified_ads.title,                
sun_classified_ads.description, 
sun_classified_ads.maker, 
sun_classified_ads.model, 
sun_classified_ads.location, 
sun_classified_ads.price, 
sun_classified_ads_images.filename_mini, 
sun_classified_ads_images.size_attr_mini, 
sun_classified_ads_images.description AS image_description
FROM sun_classified_ads
INNER JOIN sun_classified_ads_images ON sun_classified_ads.ad_id =       sun_classified_ads_images.ad_id
group by sun_classified_ads.ad_id
只是提醒一下。不能保证这将返回第一个广告。不能保证图像中的三个字段实际上来自同一个记录(尽管实际上它们来自同一个记录)。然而,这可能是获得你想要的东西的最简单的方法

下面的查询确实可以满足您的要求,但要做的工作要多一些:

SELECT 
sun_classified_ads.ad_id, 
sun_classified_ads.insertion_datetime, 
sun_classified_ads.title,                
sun_classified_ads.description, 
sun_classified_ads.maker, 
sun_classified_ads.model, 
sun_classified_ads.location, 
sun_classified_ads.price, 
substring_index(group_concat(sun_classified_ads_images.filename_mini order by ad_image_id), ',', 1), 
substring_index(group_concat(sun_classified_ads_images.size_attr_mini order by ad_image_id), ',', 1), 
substring_index(group_concat(sun_classified_ads_images.description order by ad_image_id), ',', 1) AS image_description
FROM sun_classified_ads
INNER JOIN sun_classified_ads_images ON sun_classified_ads.ad_id =       sun_classified_ads_images.ad_id
group by sun_classified_ads.ad_id

这假设
ad\u image\u id
是一个可用于定义图像顺序的字段。

我现在使用的是您的第二个解决方案,它可以做到这一点。非常感谢你。