I want to get a count where the contents of a value in one row is also in the previous row.
Row | Item1 | Item2 | Item 3 |
1 | Dog | Cat | Rat
2 | Bird | Cat | Horse
3 | Horse | Dog | Rat
4 | Bird | Cat | Horse
5 | Horse | Bird | Cat
Row 2 would increase the count of Cat because Cat is in row 1 and 2
Row 3 would increase the count of Horse because Horse is also in Row 2
Row 4 would increase the count of Horse because Horse is also in Row 3
Row 5 would increase the count of Horse AND Cat because both of those appear in row 4.
There can be a max of 100 items or SKU's and I can index on any or all fields. At any given time there's probably between 1000 and 2000 rows.
I can't even wrap my head around where to begin with this query other than "SELECT * FROM table WHERE"
First, create table with all available unique values of SKU:
CREATE TABLE results(
id VARCHAR(255) NOT NULL PRIMARY KEY
);
-- All fields should be listed here one-by-one.
INSERT IGNORE INTO results (select Item1 from example);
INSERT IGNORE INTO results (select Item2 from example);
INSERT IGNORE INTO results (select Item3 from example);
Previous row could be obtained by left join primary table again with itself, i.e. LEFT JOIN example AS previous ON previous.id + 1 = example.id
.
After that we've to check that each unique result exists in example table within current row and in previous row and finally get this:
SELECT
r.*,
SUM(
CASE WHEN r.id IN (
prv.Item1, prv.Item2, prv.Item3 -- All fields should be listed here.
) THEN 1 ELSE 0 END
) AS total
FROM
results AS r
LEFT JOIN
example AS cur ON r.id IN (
cur.Item1, cur.Item2, cur.Item3 -- All fields should be listed here.
)
LEFT JOIN
example AS prv ON prv.id + 1 = cur.id
GROUP BY
r.id
ORDER BY
cur.id
;
See working example http://www.sqlfiddle.com/#!9/7ebd85/1/0