Get IDs based corresponding value pairs uniquely - mysql

Think of a table like this,
ID Value
100 1
100 2
101 1
101 2
102 1
103 2
104 1
Now i want to retrieve the IDs based on their corresponding value combination uniquely. (ie) 100 is having both 1 and 2 as values. 101 is also having 1 and 2. Now i don't want both 100 and 101. i want only one of them (either 100 or 101). similarly, i don't want both 102 and 104 since they both have values 1. i want only of them. Typically, my result should be as follows
ID
100
102
103
I want the IDs with corresponding value pairs uniquely.
i am using MYSQL. please help me write the query to find this.

You could try something like this:
select
min(id)
from (
select
id,
group_concat(value order by value) as values
from <table>
group by id
) r
group by values
How this works:
the subquery returns one row for each id, with an extra column that has all of the values (in sorted order, which is important for the next step)
the outer query selects the minimum id for each set of values

Related

MySql: merge columns fields from mutliple rows into a single one with multiple fields

I have a table bundle_group, and its records are like
group_id sku_id
1 100
1 101
2 103
2 104
For each uniq group_id, there are only 2 skus for it.
What I am looking for is a SQL that transforms the records in a form of:
group_id sku_id1 sku_id2
1 100 101
2 103 104
I have tried select group_id, group_concat(sku_id)... This does not satisfied me as all sku_ids become a single column.
Use aggregation:
SELECT
group_id,
MIN(sku_id) AS sku_id1,
MAX(sku_id) AS sku_id2
FROM yourTable
GROUP BY
group_id;
This appears to match the logic in your expected output. If not, you should state the logic determining which of the two SKU values comes first or second.

MySQL: Select a fixed value based on UNIQUE only values of another column

I have a table with values in a column called OrderID. The values aren't all unique and often two or more rows will share the same value. What I'm trying to do, when I make a Select, I want to add a fixed value based only on UNIQUE or DISTINCT values from the OrderID column. I've tried a SELECT DISTINCT but of course that just gives me distinct only rows, as I still need to return all of the data. I played around with UNION by having one query return all of the results and the other return only DISTINCT results, but I still didn't get the final result I was looking for.
Below is basically what I'm trying to accomplish. It seems like it should be easy, but I'm not sure how to tell my fixed value SELECT to only look for distinct values in a specific column. Keep in mind, my full dataset is much greater, I've just paired it down to what I think is necessary.
OrderID
123
456
789
246
357
456
123
Result I'm looking for:
OrderID || Price
123 3
456 3
789 3
246 3
123
357 3
456
579 3

sum function is returning wrong value

I have 3 tables
1.Franchiese
Id Name
1 Vivek
2.Purchase
Id Fran_id commission_amount
1 1 100
2 1 1
3.Fran_payment
Id Fran_id amount
1 1 50
My SQL Query is
select franchiese.id,franchiese.name,sum(fran_payment.amount) as paid,sum(purchase.commission_amount) as tot,sum(purchase.commission_amount)-sum(fran_payment.amount) as rem from franchiese left join fran_payment on franchiese.id=fran_payment.fran_id left join purchase on franchiese.id=purchase.fran_id
It's giving me
Id Name Tot Paid Rem
1 vivek 101 100 1
Expected Answer
Id Name Tot Paid Rem
1 vivek 101 50 51
I think you have two identical entries in the Fran_payment table. Your SQL statement should work as intended, and is giving you logically correct values, but I think you have unexpected data in your table.
You are joining 3 tables which have unequal number of rows. Purchase table has 2 rows, while fran_payment has only one. At the time of join, the row in fran_payment is repeated to match the number of rows in purchase. Hence the row is duplicated and sum becomes 50 + 50 = 100 and your data would look like something like this-
ID | Name | fran_payment.amount | purchase.comission_amount
1 | Vivek | 50 | 100
1 | Vivek | 50 | 1
Try something like this
Select fran_id, sum(fran_payment.amount) as paid from purchase;
This should work.
Also, you'll need to run a sub query to only fetch data for given entry. Or, normal sum function would return the sum of while column, irrespective of the ID.
Select id, sum(fran_payment.amount from fran_payment where fran_payment.fran_id = id) as paid from franchise;
I hope that works. All the best.
PS: It's franchise, not franchiese.

how to left join a table onto itself n-times ? And if possible, with ZendDb?

I have a bit of a hard-to-explain (mysql) sql query question:
I have a database table, that stores the parameter values, and the case id the parameter values are associated with.
The foreign key is the parent_id, and each parent can have a variable number of parameters.
This means that if there are three parameters, there are three rows, four params, four rows, etc.
There can also be multiple entries for the same parent. I need to compare the parameter VALUE for all of that parent's parameters, to get the case id. The table is something like this:
table Case
id param_value param_id parent_id caseID
----------------------------------------------
1 red 101 200 1234
2 pepper 102 200 1234
3 green 101 200 3456
4 pepper 102 200 3456
5 pink 205 250 9875
6 panther 206 250 9875
7 fuzzy 207 250 9875
This example above: there are two different types of parents: 200 and 250.
200 there are two sets for two case ids:
1234 : param 101 = red, and param 102 = pepper
3456 : param 101 = green and param 102 = pepper
The third parent is some other parent and happens to have three params (it could have even more!)
So I will know who the parent is, the param ids for that parent, and I will have the param values, and I need to find the corresponding case ID.
I could do this with two params with a select such as:
SELECT c1.caseId from case c1
INNER JOIN case c2 ON c1.caseId=c2.caseID
WHERE c1.param_id=101 and c1.param_value='red'
AND c2.param_id=102 and c1.param_value='pepper';
(this returns caseId = 1234)
but :
Using just SQL I cannot figure out how to do this with more than two inner joins (so I cannot make a similar request for the pink panther that has three params). I need to know how to make the sql query with a variable number of params.
I can do this with the raw sql in zend, but if there is some way to do this with php Zend, then I am all ears!
Assumming that there is a constraint in the case table:
CONSTRAINT UNIQUE (param_id, parent_id, caseID )
which means, that the table cannot contain duplicate rows with the same values of these three fields, for example the below situation cannot happen:
id param_value param_id parent_id caseID
----------------------------------------------
1 red 101 200 1234
2 pepper 101 200 1234
then the below query could be used to retrieve case id for any number of parameters (below is an example for 2 parameters):
SELECT caseID
FROM cas
WHERE (param_id, param_value) IN
(
(101,'red'),
(102,'pepper')
)
GROUP BY caseID
-- a number 2 below - is a number of parameters pairs within the IN clause
HAVING count(distinct param_id) = 2
Demo --> http://www.sqlfiddle.com/#!2/a9f4e/4

MySQL SELECT query - one cell to multiple rows

In MySQL I have one particular cell with data something like this
5,6,7,8,9
If I need to search for specific 2 numbers one after another I do a query with LIKE statement for those 2 particular numbers. For ex. I need to check if there's a row with numbers 6 & 7 *in a row* I do
SELECT * FROM table WHERE column LIKE '%,6,7,%' OR column LIKE '%,6,7' OR column LIKE '6,7,%'
It's little redundant and clumsy. If I 'convert' those numbers into multiple rows, for ex. every number would become it's own row with column 'numbers' ordered with 'sort' column so I know the order of rows.
id numbers sort
55 8 4
56 6 2
57 5 1
58 7 3
59 9 5
...
What's the identical query for this case? So I would have the same result as with the query above. I need to order the query with sort column and check if the numbers 6,7 are occurring one after another with that sorting.
Should be something like this. (if I understood right your problem). It will return nothing if the 2 numbers are not in sequence by the sort column.
select *
from table t1
join table t2 on t1.sort=t2.sort+1
where t1.numbers=6 and t2.numbers=7
if you do not know which one should be first you can use it like this:
select *
from table t1
join table t2 on t1.sort=t2.sort+1 or t1.sort+1=t2.sort
where t1.numbers=6 and t2.numbers=7
Are the numbery always incremented by one or can they have any value?
I'm proposing the following table structure
id col1 col2 rowid
1 1 2 1
2 2 3 1
3 1 4 2