返回与变量id相同的前10个最常出现的值。 3米+行

时间:2015-12-06 17:18:59

标签: php mysql sql

EDIT ::已解决当while循环是打印结果的正确选项时,我正在使用for循环。非常感谢所有人在下面做出贡献..我已经离开了以下所有步骤以供参考,但这里是解决方案和工作代码。现在要清理我的数据,看看它是如何运行的,而不是那么大的'数据呵呵!

$db = new PDO($dsn, $db_user, $db_pass);
$query = $db->prepare("SELECT brand
FROM transactions
WHERE
  id IN (SELECT id FROM transactions WHERE brand = :brand1)
    AND brand <> :brand1
GROUP BY brand
ORDER BY COUNT(*) DESC
LIMIT 10");
$query->bindparam(":brand1", $brand);
$query->execute();

echo "<table>";


while($row = $query->fetch(PDO::FETCH_ASSOC)) {
    echo "<tr><td>".$row['brand']."</td</tr>";

}

echo "</table>";

为了更好地了解情况,我有交易级销售数据,我想对其进行非常简单的品牌级别购物篮分析/亲和力分析。

编辑::下面的实际架构和示例工作数据。

在我的页面上,我将有一个下拉框,可以选择一个品牌。出于这个问题的目的&#39; Brand1&#39;。然后执行一个查询,列出前10个最常出现的品牌,这些品牌也出现在表中,其ID与下拉列表中选择的ID相同。

基于数据的输出将是

brand2
brand4
brand3
brand5

该表包含300万行,因此我不认为我可以将该批量加载到内存中。但即使查询本身,我也很容易知道如何检索表中最常见的十大值。但要根据它是否与变量共享和id来实现它超出了我目前的技能水平。

所以我请求专家帮助我采取下一步能够使用php / mysql处理大数据。我怎么能说出这样的问题。

编辑::尝试1

$brand = "Brand1";


$db = new PDO($dsn, $db_user, $db_pass);
$query = $db->prepare("SELECT brand
FROM brand
WHERE
  id IN (SELECT id FROM brand WHERE brand = :brand1)
    AND brand <> :brand1
GROUP BY brand
ORDER BY COUNT(*) DESC
LIMIT 10");
$query->bindparam(":brand1", $brand);
$query->execute();
$row = $query->fetch(PDO::FETCH_ASSOC);

echo "<table>";


for($i=0;$i<10;$i++) {
    echo "<tr><td>".$row['brand']."</td</tr>";
    $i++;
}

echo "</table>";

上述回报,&#34; Brand2&#34; 5次。 (我只使用我的OP中的小样本数据)。这是我的循环问题,因为它与建议的两种类型的查询都类似。以下是供参考的架构:

--
-- Database: `transactions`
--

-- --------------------------------------------------------

--
-- Table structure for table `brand`
--

CREATE TABLE `brand` (
  `id` int(11) NOT NULL,
  `brand` varchar(25) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `brand`
--

INSERT INTO `brand` (`id`, `brand`) VALUES
(1, 'Brand1'),
(1, 'Brand1'),
(1, 'Brand2'),
(1, 'Brand3'),
(1, 'Brand4'),
(2, 'Brand1'),
(2, 'Brand2'),
(2, 'Brand3'),
(3, 'Brand1'),
(3, 'Brand2'),
(4, 'Brand1'),
(4, 'Brand2'),
(5, 'Brand1'),
(5, 'Brand2'),
(5, 'Brand4'),
(5, 'Brand5'),
(6, 'Brand2'),
(6, 'Brand3'),
(7, 'Brand1'),
(7, 'Brand2'),
(7, 'Brand3');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `brand`
--
ALTER TABLE `brand`
  ADD KEY `brand` (`id`,`brand`) USING BTREE;

3 个答案:

答案 0 :(得分:1)

在SQL中,您可以将其表达为:

select b.brand
from brand b join
     brand b1
     on b.id = b1.id and b1.brand = 1 and b1.brand <> b.brand
group by b.brand
order by count(*) desc
limit 10;

您可以通过brand(brand, id)上的索引以及brand(id)获得一些性能优势。

根据数据和用户要求,我不确定您是否会从此查询中获得所需的性能。但是,首先让逻辑起作用,然后研究性能。

答案 1 :(得分:1)

我会将其表达为

SELECT brand
FROM brand
WHERE
  id IN (SELECT id FROM brand WHERE brand = 'brand1')
    AND brand <> 'brand1'
GROUP BY brand
ORDER BY COUNT(*) DESC
LIMIT 10;

这可以避免JOIN的成本,并删除未在示例结果集中显示的用户所选品牌。

正如Gondon Linoff所提到的,索引可能会大大提高性能。

答案 2 :(得分:0)

下面的SQL查询说“只返回10条记录,从记录16开始(OFFSET 15)”:

SELECT * FROM <YOURTABLE> LIMIT 10 OFFSET 15