I will better explain with tables:
table size
-----------------------------
id | type | size | cont_id |
-----------------------------
1 | GP | 30 | 21 |
2 | FR | 30 | 21 |
3 | UP | 40 | 21 |
4 | GT | 50 | 32 |
5 | UP | 40 | 32 |
-----------------------------
table buy
-------------------
cont_id | cus_nam |
-------------------
21 | xxx |
32 | zzz |
------------------
Now I want to combine two column into one and then do group_concat
This is what I want to do, output table should be like this:
------------------------------------
type | cont_id |
-----------------------------------
30GP ,30FR,40UP | 21 |
50GT , 40UP | 32 |
------------------------------------
You only need the first table. This is almost a basic aggregation:
select group_concat(size, type), cont_id
from size
group by cont_id;
Related
I have a problem in which I have a STUDENT table as
+-------------+-------------+-------------+-------------+---------------+
| roll_number | name | subject_one | subject_two | subject_three |
+-------------+-------------+-------------+-------------+---------------+
| 1 | Sheila | 32 | 48 | 64 |
| 2 | Rachel | 24 | 21 | 25 |
| 3 | Christopher | 55 | 12 | 10 |
+-------------+-------------+-------------+-------------+---------------+
I want the print the output as
+-------------+-------------+-------------+
| roll_number | name | total |
+-------------+-------------+-------------+
| 1 | Sheila | 144|
| 2 | Rachel | 70 |
| 3 | Christopher | 77 |
+-------------+-------------+-------------+
and select all student having marks greater than 75 ??
How can I achieve this using MYSQL ??
I think you just need the aggregate functions and using them is enough. I am not sure if it can help you or not.
SELECT roll_number , name , (subject_one + subject_two + subject_three) AS total FROM STUDENT HAVING total > 75 ;
Let's say i have a user table like this :
+----+-----------+----------------------+------+
| ID | Name | Email | Age |
+----+-----------+----------------------+------+
| 1 | John | john.doe1#mail.com | 24 |
| 2 | Josh | josh99#mail.com | 29 |
| 3 | Joseph | joseph410#mail.com | 21 |
| 4 | George | gge.48#mail.com | 28 |
| 5 | Joseph | jh.city89#mail.com | 24 |
| 6 | Kim | kimsd#mail.com | 32 |
| 7 | Bob | bob.s#mail.com | 38 |
| 8 | Joseph | psa.jos#mail.com | 34 |
| 9 | Joseph | joseph.la#mail.com | 28 |
| 10 | Jonathan | jonhan#mail.com | 22 |
+----+-----------+---------+------------+------+
In the actual, the database consists of more data and some of the data is duplicated, with more than two records. But the point is i want to get only the first and the second row of the duplicated rows that contains the name of "Joseph", How can i achieve this ? My code so far...
User::withTrashed()->groupBy('name')->havingRaw('count("name") >= 1')->get();
With that code the result will retrieve :
+----+-----------+----------------------+------+
| ID | Name | Email | Age |
+----+-----------+----------------------+------+
| 1 | John | john.doe1#mail.com | 24 |
| 2 | Josh | josh99#mail.com | 29 |
| 3 | Joseph | joseph410#mail.com | 21 |
| 4 | George | gge.48#mail.com | 28 |
| 6 | Kim | kimsd#mail.com | 32 |
| 7 | Bob | bob.s#mail.com | 38 |
| 10 | Jonathan | jonhan#mail.com | 22 |
+----+-----------+---------+------------+------+
And i use this code to try to get the second duplicated row :
User::withTrashed()->groupBy('name')->havingRaw('count("name") >= 2')->get();
The result is still same as the mentioned above :
+----+-----------+----------------------+------+
| ID | Name | Email | Age |
+----+-----------+----------------------+------+
| 1 | John | john.doe1#mail.com | 24 |
| 2 | Josh | josh99#mail.com | 29 |
| 3 | Joseph | joseph410#mail.com | 21 |
| 4 | George | gge.48#mail.com | 28 |
| 6 | Kim | kimsd#mail.com | 32 |
| 7 | Bob | bob.s#mail.com | 38 |
| 10 | Jonathan | jonhan#mail.com | 22 |
+----+-----------+---------+------------+------+
I want the result is to get record that have the id "5" with name "Joseph" like this :
+----+-----------+----------------------+------+
| ID | Name | Email | Age |
+----+-----------+----------------------+------+
| 1 | John | john.doe1#mail.com | 24 |
| 2 | Josh | josh99#mail.com | 29 |
| 4 | George | gge.48#mail.com | 28 |
| 5 | Joseph | jh.city89#mail.com | 24 |
| 6 | Kim | kimsd#mail.com | 32 |
| 7 | Bob | bob.s#mail.com | 38 |
| 10 | Jonathan | jonhan#mail.com | 22 |
+----+-----------+---------+------------+------+
But it seems only the first duplicate row is retrieved and i can't get the second duplicated row, can anybody give me suggestion ?
Let's start from your query
User::withTrashed()->groupBy('name')->havingRaw('count("name") >= 1')->get();
This will show all groups of rows whose count equals to 1 ore more. and this is the description of DISTINCT.
If you want to get only duplicate records you should get groups whose count is LARGER than 1.
The other thing to notice here is that a non-aggrigated column will be chosen randomly. because when you get a name and it's count, for example if you select name,count(name), email (email is not in the group by clause - not aggregated), and 4 rows have the same name. so you'll see:
+--------+-------------+-------+
| Name | Count(Name) | Email |
+--------+-------------+-------+
| Joseph | 4 | X |
+--------+-------------+-------+
what do you expect instead of X? which one of the 4 emails? actually, in SQLServer it's forbidden to select a non-aggrigated column and other databases will just give you a random one of the counted 3.
see this answer for more details it's explained very well: Do all columns in a SELECT list have to appear in a GROUP BY clause
So, we'll use having count(name) > 1 and select only the aggregated column name
DB::from('users')->select('name')->groupBy('name')->havingRaw('count("name") > 1')->get();
This should give you (didn't test it) this:
+--------+-------------+
| name | Count(name) |
+--------+-------------+
| Joseph | 4 |
+--------+-------------+
This will give you all names who have 2 or more instances. you can determine the number of duplicates in the having clause. for example having count(name) = 3 will give you all names which have exactly 3 duplicates.
So how to get the second duplicate? I have a question for that:
What is the first (original) duplicate? is it the one with the oldest created_at or the oldest updated_at ? or maybe some other condition?. because of that you should make another query with order by clause to give you the duplicates in the order most convenient to you. for example:
select * from `users` where `name` in (select `name` from users group by `name` having count(`name`) > 1) order by `id` asc
which will give:
+----+-----------+----------------------+------+
| ID | Name | Email | Age |
+----+-----------+----------------------+------+
| 3 | Joseph | joseph410#mail.com | 21 |
| 5 | Joseph | jh.city89#mail.com | 24 |
| 8 | Joseph | psa.jos#mail.com | 34 |
| 9 | Joseph | joseph.la#mail.com | 28 |
+----+-----------+---------+------------+------+
I have a table called transactions that looks like this:
transactions:
| id | PartNumber | Quantity |
I know that I can use the COUNT property in MySQL, which would give me the the duplicate part numbers in a new column called total_quantity:
SELECT COUNT(transactions.id) AS total_quantity
FROM transactions
GROUP BY transactions.PartNumber
However, now I already have an existing quantity column and want to compute a new count quantity taking into account the previous one as well and updating it in the existing quantity column
What's the most efficient way of doing this?
For example: I want to go from this:
transactions
| id | PartNumber | Quantity |
| 1 | 123 | 1 |
| 2 | 124 | 2 |
| 3 | 125 | 2 |
| 4 | 124 | 2 |
| 5 | 124 | 3 |
| 6 | 126 | 4 |
| 7 | 125 | 1 |
| 8 | 127 | 2 |
To this:
transactions
| id | PartNumber | Quantity |
| 1 | 123 | 1 |
| 2 | 124 | 7 |
| 3 | 125 | 3 |
| 4 | 126 | 4 |
| 5 | 127 | 2 |
You can use this sql request :
SELECT PartNumber, sum(Quantity) as 'SumQuantity' FROM transactions GROUP BY PartNumber
It will gives you sometings like this :
transactions
| PartNumber | SumQuantity |
| 123 | 1 |
| 124 | 7 |
| 125 | 3 |
| 126 | 4 |
| 127 | 2 |
You can find a code sample on SQL Fiddle
I am trying to set up a SSRS report where I combine 2 datasets connected to 2 different data sources. The parameter #ParentProductID is used in both dataset queries.
DataSet01
ParentProductID
ChildProductID
Quantity
Example output
+-----------------+----------------+----------+
| ParentProductID | ChildProductID | Quantity |
+-----------------+----------------+----------+
| 1 | 20 | 50 |
| 1 | 30 | 10 |
| 1 | 40 | 10 |
| 1 | 50 | 10 |
+-----------------+----------------+----------+
DataSet02
ParentProductID
CompanyID
Example output
+-----------------+-----------+
| ParentProductID | CompanyID |
+-----------------+-----------+
| 1 | 100 |
| 1 | 200 |
+-----------------+-----------+
As the data is from 2 different data sources, I have had no luck joining the data in a single dataset query.
What I want is to display a matrix with the following data:
+-----------------+-----------+
| ParentProductID | CompanyID |
+-----------------+-----------+
| ChildProductID | Quantity |
+-----------------+-----------+
So far I’ve managed to combine the table using lookup function. (placeholder expression in "CompanyID" column)
=Lookup(Fields!ParentProductID.Value.tostring(), Fields!ParentProductID.Value.tostring(), Fields!CompanyID.Value, "DataSet02a_uCommerceOrder")
However, this only combines the first company where the parent ID matches.
+----+-----+
| 1 | 100 |
+----+-----+
| 20 | 50 |
| 30 | 10 |
| 40 | 10 |
| 50 | 10 |
+----+-----+
I wish to combine the datasets, so I get a column for each CompanyID, and not just the first occurrence.
+----+-----+-----+
| 1 | 100 | 200 |
+----+-----+-----+
| 20 | 50 | 50 |
| 30 | 10 | 10 |
| 40 | 10 | 10 |
| 50 | 10 | 10 |
+----+-----+-----+
How can this be done in SSRS?
Can I merge the CompanyID from DataSet02 to DataSet01?
I have a query that returns a table that looks something like this:
+------+----------+-------+------+----+
| pID | name | month | q | s |
+------+----------+-------+------+----+
| 1468 | bob | 2 | 1 | 14 |
| 1469 | bob | 2 | 1 | 2 |
| 1470 | bob | 2 | 1 | 9 |
| 1468 | bob | 3 | 1 | 7 |
| 1469 | bob | 3 | 1 | 8 |
| 1470 | bob | 3 | 1 | 11 |
+------+----------+-------+------+----+
and I would like the output to be
+----------+-------+------+-----+
| name | month | q | sub |
+----------+-------+------+-----+
| bob | 2 | 1 | 25 |
| bob | 3 | 1 | 26 |
+----------+-------+------+-----+
Essentially, I want the first two columns of my output to be name, month and q grouped by name and month (they will always have the same data per line in this grouping) and I want the last column to be the SUM of s grouped by name only.
Thanks.
It should be something like this:
SELECT name, month, q, SUM(sub)
FROM table
GROUP BY name, month, q