Show single set of results from two tables - mysql

I am trying to show the results of items from one table where the count from another table equals a number from the first. I have been stuck on how to go about doing this for a couple weeks now so iv finally decided to ask for help. Im having a hard time explaining exactly what it is i need but i will try my best.
I am using PDO to interact with my database which is mysql.
For instance i have two tables:
table 1
-----------------
key | name | total
1 | item 1 | 3
2 | item 2 | 4
3 | item 3 | 2
table 2
-----------------
key | table1 key
1 | 1
2 | 2
3 | 3
4 | 1
5 | 1
6 | 3
7 | 2
8 | 2
So in this case there would be 3/3 items for item 1, 3/4 items for item 2, and 2/2 items for item 3. So it would show item 1 and item 3 as a result because the count for those two equal the total from table one.
I hope I explained this well enough.

If you want a sql query to do that, try this:
select t1.*
from table1 t1
inner join (
select table1_key, count(1) as cnt from table2 group by table1_key
) t2 on t1.key = t2.table1_key and t1.total = t2.cnt
SQLFiddel Demo

Related

MySQL - select distinct value from two column

I have a table with the following structure:
IdM|IdS
-------
1 | 2
1 | 3
1 | 4
2 | 1
2 | 3
2 | 4
3 | 1
3 | 2
3 | 3
3 | 4
How could I make a select statement on this table, which will return some rows of this table, where in each row, a specific id appears only one, indifferent on which column it is specified?
For the above result set, I would like a query that would return:
-------
1 | 2
3 | 4
-------
To give another example, if you would omit the first row in the original dataset:
IdM|IdS
-------
1 | 3
1 | 4
2 | 1
2 | 3
2 | 4
3 | 1
3 | 2
3 | 3
3 | 4
the result set should be:
-------
1 | 3
2 | 4
-------
That's actually an interesting problem. If I follow you correctly, you want to iterate through the dataset and only retain rows where both values were never seen before. You could use a recursive query:
with recursive
data as (
select idm, ids, row_number() over(order by idm, ids) rn
from mytable
where idm <> ids
),
cte as (
select idm, ids, rn, 1 as to_keep , concat(idm, ',', ids) visited from data where rn = 1
union all
select d.idm, d.ids, d.rn,
(not find_in_set(d.idm, c.visited) and not find_in_set(d.ids, c.visited)),
case when (not find_in_set(d.idm, c.visited) and not find_in_set(d.ids, c.visited))
then concat_ws(',', c.visited, d.idm, d.ids)
else c.visited
end
from cte c
inner join data d on d.rn = c.rn + 1
)
select idm, ids from cte where to_keep
The first CTE enumerates the rows ordered by both columns. Then the recursive query walks the resultset, checks if both values are new, and sets a flag accordingly of the columns. Flagged numbers are retained to be used for filtering in the following iteration.
Demo on DB Fiddle
Note that, given your requirement, not all values may appear in the resultset. Consider the following dataset:
idm ids
+-----+---
1 2
1 3
1 4
Your logic will only return the first row.

MySQL row to columns

I have searched all over the internet and I have had no luck in finding the answer to my question. I hope this has not specifically been posted yet.
I am trying to change the data from row to columns.
Here is my current query:
SELECT * FROM wp_rg_lead_detail ORDER BY id
Gives me the result below:
id lead_id form_id field_number value
1 1 1 1 A
2 1 1 2 B
3 1 1 3 C
4 2 1 1 A
5 2 1 2 B
6 2 1 3 C
The lead_id is the spesific entry and the field number is the order of the value.
The result I am looking for is:
|Column 1|Column 2|Column 3|
----------------------
| 1 | 2 | 3 |
| A | B | C |
If my tables is confusing, please see attached images here:
Current result
Wished result
Any help or pointers would be highly appricated.
u can choose what u want to show in sql command.
SELECT `value`,`field_number` FROM wp_rg_lead_detail ORDER BY id
but if u want to change schema of table it's not work.
u can retrieve data with select query thene insert what u want in new table.

Find rows without corresponding second row in MySQL

Given the following table:
type | area | shelf
-----|------|------
1 | a | 5
2 | a | 5
2 | a | 6
1 | a | 7
2 | a | 7
1 | b | 3
An area / shelf combination entry with type 2 always needs a corresponding entry with type 1. Type 1 can exist on its own (e.g. last row).
How can I find orphan type 2 rows (rows with type 2 without corresponding row with type 1) such as the third row?
You can do this with aggregation and a having clause:
select shelf, area
from t
group by shelf, area
having sum(type = 2) > 0 and -- at least one type 2
sum(type = 1) = 0; -- no type 1
Are you looking for this..
SELECT t2.*
FROM yourtable t1
RIGHT JOIN yourtable t2 ON t1.area = t2.area
AND t1.shelf=t2.shelf
AND t1.`type`=1
AND t2.`type`=2
WHERE t1.`type` IS NULL

Fetching crossed records from the database

I have the following table structure:
structure_id | substructure_id | hash_id
1 1 1
1 1 2
1 2 1
2 1 3
2 1 1
2 2 2
And I want to fetch an intersection for each structure id how many hashes intersect with other structure ids, with the same hashes in different substructures being distinct. What I mean is the following output:
structure_id | structure_intersected_id | count
1 1 2
1 2 2
2 2 3
2 1 2
Is this possible to achieve with MySQL? So far I have the following query:
select t1.structure_id, t2.structure_id, count(*)
from table t1
inner join table t2 on t1.hash_id = t2.hash_id
group by t1.structure_id, t2.structure_id;
But it doesn't remove duplicated substructure hashes, and is not correct for 1-1, 2-2, 3-3, etc. structure_id pairs.
How can I solve this?

mysql query for items with multiple conditions (item options)

What I like to achieve is
a: display all Items that are in all of the selected category's
b: return / update the category list with category's available based on selection
I like items to be stored and be found by use of the adjacency list model or nested sets.
I've experimented with both and may use advice what would be the best for this case.
Currently I'm using (testing with) the adjacency list model like this:
items:
ID | item_name
====================
1 | car
2 | boat
3 | bike
items_cats: (many to many)
iid | cid
====================
1 | 1
1 | 2
1 | 4
1 | 7
2 | 1
2 | 3
2 | 4
2 | 7
3 | 1
3 | 3
3 | 4
3 | 8
categorys:
ID | cat_name | parent_id
========================
1 | safety: | 0 (0 = no parent)
2 | safe | 1
3 | dangerous | 1
4 | fun: | 0
5 | a bit | 5
6 | boring | 5
7 | funny | 5
8 | cool | 5
So its no problem to get items based on cid but how would you:
1st: selection:
1- Display all items who have cat id: cid 7 (funny)?
2- return (array/object) of all category's who have items that also contain cid 7?
Would you all do this in one query or would two be more efficient?
2nd: selection:
3- Display all items who have cat id: cid 7 and also contain cat id '3' (dangerous)
4- return (array/object) of all category's who have items that contain cid 7 and cid 3?
For selecting on multiple category's I found the flowing solution. Is this a good one and would there be to gain any performance especially when the number of category's grow?
SELECT
DISTINCT t1.product_id, t1.category_id
FROM
items_cats t1
INNER JOIN
items_cats t1b
ON t1.iid =t1b.iid
WHERE
t1.cid=3 AND
t1b.cid=7
To get a list of all items that have category ID = 7, start with your many:many table
select
i.item_name
from
items_cat ic
join items i
on ic.iid = i.id
where
ic.cid = 7
to get all categories associated with any item that has the category ID of 7, you can expand from the first and get categories associate for those item IDs
select DISTINCT
ic2.cid,
c.cat_name,
coalesce( CatParent.cat_name, "" ) as ParentCategoryName
from
( select distinct ic.iid
from items_cat ic
where ic.cid = 7 ) QualifiedItems
JOIN items_cat ic2
on QualifiedItems.iid = ic2.iid
JOIN categorys c
on ic2.cid = c.id
LEFT JOIN categorys CatParent
on c.parent_id = CatParent.ID
For 3 and 4, it would be similar, but to qualify BOTH (or anytime, more than one), you need to apply an OR, a GROUP BY and make sure that the final count matches those you were trying to qualify
select
i.item_name
from
items_cat ic
join items i
on ic.iid = i.id
where
ic.cid in( 3, 7 )
group by
i.item_name
having
count(*) = 2
So you can better understand and apply these principles, I'll leave the last one for you to try and implement... If you really get stuck, let me know... :)