How to get count of combinations from database?
I have to database tables and want to get the count of combinations. Does anybody know how to put this in a database query, therefore I haven't a db request for each trip?
Trips
| ID | Driver | Date |
|----|--------|------------|
| 1 | A | 2015-12-15 |
| 2 | A | 2015-12-16 |
| 3 | B | 2015-12-17 |
| 4 | A | 2015-12-18 |
| 5 | A | 2015-12-19 |
Passengers
| ID | PassengerID | TripID |
|----|-------------|--------|
| 1 | B | 1 |
| 2 | C | 1 |
| 3 | D | 1 |
| 4 | B | 2 |
| 5 | D | 2 |
| 6 | A | 3 |
| 7 | B | 4 |
| 8 | D | 4 |
| 9 | B | 5 |
| 10 | C | 5 |
Expected result
| Driver | B-C-D | B-D | A | B-C |
|--------|-------|-----|---|-----|
| A | 1 | 2 | - | 1 |
| B | - | - | 1 | - |
Alternative
| Driver | Passengers | Count |
|--------|------------|-------|
| A | B-C-D | 1 |
| A | B-D | 2 |
| A | B-C | 1 |
| B | A | 1 |
Has anybody an idea?
Thanks a lot!
Try this:
SELECT Driver, Passengers, COUNT(*) AS `Count`
FROM (
SELECT t.ID, t.Driver,
GROUP_CONCAT(p.PassengerID
ORDER BY p.PassengerID
SEPARATOR '-') AS Passengers
FROM Trips AS t
INNER JOIN Passengers AS p ON t.ID = p.TripID
GROUP BY t.ID, t.Driver) AS t
GROUP BY Driver, Passengers
The above query will produce the alternative result set. The other result set can only be achieved using dynamic sql.
Demo here
Related
i have table with data like this below
| id | wallet_id | wallet_name | deposit | |
|----|-----------|-------------|---------|---|
| 1 | 12 | a_wallet | 10 | |
| 2 | 14 | c_wallet | 12 | |
| 3 | 12 | a_wallet | 24 | |
| 4 | 15 | e_wallet | 50 | |
| 5 | 14 | c_wallet | 10 | |
| 6 | 15 | e_wallet | 22 | |
i want to select and group with same wallet_id, probably something like this
| wallet_id | id | wallet_name |
|-----------|----|-------------|
| 12 | 1 | a_wallet |
| | 3 | a_wallet |
| 14 | 2 | c_wallet |
| | 5 | c_wallet |
| 15 | 4 | e_wallet |
| | 6 | e_wallet |
i already try
select wallet_id, id, wallet_name from wallet group by wallet_id
but it shows like usual select query with no grouping.
Kindly need your help, thanks
We would generally handle your requirement from the presentation layer (e.g. PHP), but if you happen to be using MySQL 8+, here is a way to do this directly from MySQL:
SELECT
CASE WHEN ROW_NUMBER() OVER (PARTITION BY wallet_id ORDER BY id) = 1
THEN wallet_id END AS wallet_id,
id,
wallet_name
FROM wallet w
ORDER BY w.wallet_id, id;
Having a table name route, contains the bus_id,stop_name and position(it is the sequence of the stops).
bus travel in one way according to position
Table: route
| bus_id | stop_name | position |
|--------|-----------|----------|
| 1 | Stop_1 | 1 |
| 1 | Stop_2 | 2 |
| 1 | Stop_3 | 3 |
| 1 | Stop_4 | 4 |
| 1 | Stop_5 | 5 |
| 1 | Stop_6 | 6 |
| 1 | Stop_7 | 7 |
| 2 | Ramdom_1 | 1 |
| 2 | Ramdom_2 | 2 |
| 2 | Stop_3 | 3 |
| 2 | Stop_4 | 4 |
| 2 | Stop_5 | 5 |
| 2 | Stop_6 | 6 |
| 2 | Ramdom_3 | 7 |
Now need to find the bus_id which go from stop_3 to stop_6 i.e bus_id = 1 and 2
examples:\
from stop_1 to stop_6 = 1\
from stop_6 to Ramdom_3 = 2\
from stop_6 to stop_1 = no bus found\
Need to MYSQL query to find the above data
database used Server version: 10.4.21-MariaDB (xamp)
Select a.*, b.*
From route a
Join route b on a. bus_id=b.bus_id
Where a.position <b.position
And a.name=[stopname] and b.name=.
[stopname]
I've tried the following queries but unfortunately they don't work :(.
Worth mentioning that each customer has more than one CustomerUsers
select (a.TotalJobs / b.DaysActive) from
(select count(jr.id) as TotalJobs
from jobrequests jr, customers c, customerusers cu
where jr.customeruserid=cu.id
and cu.customerid=c.id
group by c.name) as a,
(select datediff(curdate(), from_unixtime(c.CreationTime)) as DaysActive
from customers c
group by c.name) as b
Please see below the tables
Jobs:
+----+--------------+
| ID | JobRequestID |
+----+--------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
| 8 | 3 |
| 9 | 3 |
| 10 | 3 |
| 11 | 4 |
| 12 | 4 |
| 13 | 5 |
| 14 | 5 |
| 15 | 6 |
| 16 | 7 |
| 17 | 8 |
| 18 | 8 |
| 19 | 9 |
| 20 | 10 |
+----+--------------+
JobRequests:
+----+---------------+
| ID | CustomeUserID |
+----+---------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 4 |
| 8 | 4 |
| 9 | 4 |
| 10 | 5 |
| 11 | 5 |
| 12 | 5 |
| 13 | 6 |
| 14 | 6 |
| 15 | 7 |
+----+---------------+
CustomerUsers:
+----+------------+
| ID | CustomerID |
+----+------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 2 |
| 7 | 2 |
| 8 | 3 |
| 9 | 3 |
| 10 | 4 |
+----+------------+
Customers:
+----+------+--------------+
| ID | Name | CreationTime |
+----+------+--------------+
| 1 | a | 1415814194 |
| 2 | b | 1415814194 |
| 3 | c | 1415986994 |
| 4 | d | 1415986994 |
+----+------+--------------+
For the moment it returns 16 results (4X4), dividing each result from 1st sub-query to each result from the 2nd one (each of these sub-queries return 4 results). Can anyone please help me to get this to divide only 1 result from sub-query 1 to it's corespondent from sub-query 2?
Thank you in advance.
I suspect that you can do what you want this a query like this:
select c.name, count(*) / (datediff(curdate(), from_unixtime(c.CreationTime))
from customerusers cu join
jobrequests jr
on jr.customeruserid = cu.id join
customers c
on cu.customerid = c.id
group by c.name;
I don't see why you need two subqueries for this.
I'm guessing you need to join your results together -- as currently written, you're producing a cartesian product.
Try something like this adding c.id to each subquery (it's better to group by it presumably rather than the name):
select (a.TotalJobs / b.DaysActive)
from (
select c.id,
count(jr.id) as TotalJobs
from jobrequests jr
join customers c on jr.customeruserid=cu.id
join customerusers cu on cu.customerid=c.id
group by c.id) a join (
select c.id,
datediff(curdate(), from_unixtime(c.CreationTime)) as DaysActive
from customers c
group by c.id) b on a.id = b.id
Please note, I've updated your syntax to use the more standard join syntax.
I have searched and gone through the available topics similar to mine. But, failed to find that satisfies my requirements. Hence, posting it here.
I have four tables as follows:
"Organization" table:
--------------------------------
| org_id | org_name |
| 1 | A |
| 2 | B |
| 3 | C |
"Members" table:
----------------------------------------------
| mem_id | mem_name | org_id |
| 1 | mem1 | 1 |
| 2 | mem2 | 1 |
| 3 | mem3 | 2 |
| 4 | mem4 | 3 |
"Resource" table:
--------------------------------
| res_id | res_name |
| 1 | resource1 |
| 2 | resource2 |
| 3 | resource3 |
| 4 | resource4 |
"member-resource" table:
--------------------------------------------
| sl_no | mem_id | res_id |
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
| 4 | 4 | 3 |
| 5 | 3 | 4 |
| 6 | 2 | 3 |
| 7 | 4 | 3 |
I want to find out the total number of distinct resources according to organizations. Expected output is as follows:
| org_name | Total Resources |
| A | 3 |
| B | 1 |
| C | 1 |
I also want to find out the total number of shared resources according to organizations. Expected output is as follows:
| org_name | Shared Resources |
| A | 1 |
| B | 0 |
| C | 1 |
Any help in this regard will highly be appreciated.
Regards.
It is much simpler than you think, particularly because you don't even need the resource table:
SELECT o.org_name, COUNT(DISTINCT mr.res_id) TotalResources
FROM member_resource mr
JOIN members m ON mr.mem_id = m.mem_id
JOIN organization o ON m.org_id = o.org_id
GROUP BY o.org_id
Output:
| ORG_NAME | TOTALRESOURCES |
|----------|----------------|
| A | 3 |
| B | 1 |
| C | 1 |
Fiddle here.
Try this query below.
SELECT org_name, COUNT(DISTINCT res_id)
FROM organization, members, member-resource
WHERE members.mem_id = member-resource.mem_id
AND organization.org_id = members.org_id
GROUP BY org_id, org_name
Is there a way in SQL (MySQL) to do a "round robin" ORDER BY on a particular field?
As an example, I would like to take a table such as this one:
+-------+------+
| group | name |
+-------+------+
| 1 | A |
| 1 | B |
| 1 | C |
| 2 | D |
| 2 | E |
| 2 | F |
| 3 | G |
| 3 | H |
| 3 | I |
+-------+------+
And run a query that produces results in this order:
+-------+------+
| group | name |
+-------+------+
| 1 | A |
| 2 | D |
| 3 | G |
| 1 | B |
| 2 | E |
| 3 | H |
| 1 | C |
| 2 | F |
| 3 | I |
+-------+------+
Note that the table may have many rows, so I can't do the ordering in the application. (I'd obviously have a LIMIT clause as well in the query).
I'd try something like:
SET #counter = 0;
SELECT (#counter:=#counter+1)%3 as rr, grp, name FROM table ORDER by rr, grp
What you can do is create a temporary column in which you create sets to give you something like this:
+-------+------+-----+
| group | name | tmp |
+-------+------+-----+
| 1 | A | 1 |
| 1 | B | 2 |
| 1 | C | 3 |
| 2 | D | 1 |
| 2 | E | 2 |
| 2 | F | 3 |
| 3 | G | 1 |
| 3 | H | 2 |
| 3 | I | 3 |
+-------+------+-----+
To learn how to create the sets, have a look at this question/answer.
Then its a simple
ORDER BY tmp, group, name
You can use MySQL variables to do this.
SELECT grp, name, #row:=#row+1 from table, (SELECT #row:=0) r ORDER BY (#row % 3);
+------+------+--------------+
| grp | name | #row:=#row+1 |
+------+------+--------------+
| 1 | A | 1 |
| 2 | D | 4 |
| 3 | G | 7 |
| 1 | B | 2 |
| 2 | E | 5 |
| 3 | H | 8 |
| 1 | C | 3 |
| 2 | F | 6 |
| 3 | I | 9 |
+------+------+--------------+