Joining and Ordering two tables that have same columns - php

I am trying to combine these two tables then order it by one column (stamp), and aliasing the second table's id field. I've tried joins, merges, but nothing seems to work. I am also trying to group them by the mm
Table note
id | mm | stamp |
==========================
1 | 5 | 2009-12-11 |
2 | 33 | 2010-09-10 |
3 | 22 | 2011-07-08 |
4 | 1 | 2012-05-06 |
Table note_admin
id | mm | stamp |
==========================
1 | 5 | 2009-08-15 |
2 | 5 | 2011-11-11 |
3 | 5 | 2012-01-08 |
4 | 35 | 2012-02-06 |
Query I thought would work:
(SELECT * FROM note WHERE mm=5)
UNION
(SELECT id AS a_id, mm, stamp FROM note_admin WHERE mm=5)
ORDER BY stamp DESC
Expected Result
id | a_id | mm | stamp |
================================
| 3 | 5 | 2012-01-08 |
| 2 | 5 | 2011-11-11 |
1 | | 5 | 2009-12-11 |
| 1 | 5 | 2009-08-15 |
I don't even know if this is possible. I found a way to sort this in PHP but it would be much easier if it can be done in mySQL. Thanks.

I think you mean this, note the same 4 column names (not sure about the order by though):
(SELECT a_id as NULL, note.* FROM note WHERE mm=5) UNION (SELECT id AS a_id, NULL as id, mm, stamp FROM note_admin WHERE mm=5) ORDER BY stamp DESC

Related

Find the ranking for Concatenated rows in mysql

I have a table with concatenated values within both rows, I am therefore uniquely retrieve ranking for each row in the tables.
UPDATE
The other tables has been added to question
NamesTable
NID | Name |
1 | Mu |
2 | Ni |
3 | ices |
GroupTable
GID | GName |
1 | GroupA |
2 | GroupB |
3 | GroupC |
MainTable
| NID | Ages | Group |
| 1 | 84 | 1 |
| 2 | 64 | 1 |
| 3 | 78 | 1 |
| 1 | 63 | 2 |
| 2 | 25 | 2 |
| 3 | 87 | 2 |
| 1 | 43 | 3 |
| 2 | 62 | 3 |
| 3 | 37 | 3 |
Now the first Name is equated to the first age in the table, I am able to equate them using php and foreach statements, Now the problem is with the ranking of the ages per each group. I am ranking the names uniquely on each row or group.
Results which is expected
| Names | Ages | Group | Ranking |
| Mu,Ni,ices | 84,64,78 | 1 | 1,3,2 |
| Mu,Ni,ices | 63,25,87 | 2 | 2,3,1 |
| Mu,Ni,ices | 43,62,37 | 3 | 2,1,3 |
In my quest to solving this, I am using GROUP_CONCAT, and I have been able to come to this level in the below query
SELECT
GROUP_CONCAT(Names) NAMES,
GROUP_CONCAT(Ages) AGES,
GROUP_CONCAT(Group) GROUPS,
GROUP_CONCAT( FIND_IN_SET(Ages, (
SELECT
GROUP_CONCAT( Age ORDER BY Age DESC)
FROM (
SELECT
GROUP_CONCAT(Ages ORDER BY Ages DESC ) Age
FROM
`MainTable` s
GROUP by `Group`
) s
)
)) rank
FROM
`MainTable` c
GROUP by `Group`
This actually gives me the below results.
| Names | Ages | Group | Ranking |
| 1,2,3 | 84,64,78 | 1 | 7,9,8 |
| 1,2,3 | 63,25,87 | 2 | 5,6,4 |
| 1,2,3 | 43,62,37 | 3 | 2,1,3 |
The only problem is that the ranking Values increase from 1 to 9 instead of ranking each row uniquely. Its there any idea that can help me cross over and fix this? I would be grateful for your help. Thanks

how to calculate unique column values in mysql

Here is my data
cardNo| userName| tablename| hours | date
1 | a | a | 12 | 12-06-2015
1 | a | a | 5 | 11-06-2015
2 | b | b | 3 | 15-06-2015
1 | a | a | 8 | 12-06-2015
2 | b | b | 3 | 21-06-2015
1 | a | a | 12 | 14-06-2015
2 | b | b | 10 | 8-06-2015
cardNo is unique. I need to display all details and total hours for each card, like:
cardNo | userName | tablename | totalhours
1 | a | a | 37
2 | b | b | 16
It's simple SUM() with GROUP BY:
SELECT cardNo,sum(hours)
FROM yourtable
GROUP BY cardNo;
I left it as an exercise for the OP to include userName and tablename columns into the query
SELECT cardNo,userName, tablename, sum(hours) hours
FROM Table_1 GROUP BY cardNo,userName,tablename

MySQL MIN() limit by column

I have a MySQL table that is formatted as follows:
group_clue:
---------------------------------------------------
| id | group_id | clue_id | completed | run_order |
---------------------------------------------------
| 1 | 1 | 2 | 1 | 1 |
| 2 | 1 | 6 | 1 | 2 |
| 3 | 1 | 4 | 1 | 3 |
| 4 | 1 | 3 | 0 | 4 |
| 5 | 1 | 1 | 0 | 5 |
| 6 | 1 | 5 | 0 | 6 |
| 7 | 2 | 9 | 1 | 1 |
| 8 | 2 | 2 | 0 | 2 |
...
---------------------------------------------------
The data above in the group_clue is constructed such that each group_id has every clue_id at some run_order (ranging from 1 to the number of clue_ids and not repeating for a particular group).
First Question
I want to create a table showing the first clue_id for each group_id where completed = 0 when ordered by run_order (aliased as current_clue). Using the above example, this would give:
---------------------------
| group_id | current_clue |
---------------------------
| 1 | 3 |
| 2 | 2 |
---------------------------
My preliminary attempt is:
SELECT group_id, MIN(clue_id) as current_clue
FROM group_clue
WHERE completed = 0
GROUP BY group_id
However, this returns the same clue_id for each group_id.
Second Question
From the data in the first question, I would like to compose a final table where I GROUP_CONCAT() these results so that it contains every current_clue and each group_id that contains that current_clue. I would also like it ordered from those clues with the most group_ids to those with the fewest. An example resulting table is:
--------------------
| clue | group_ids |
--------------------
| 3 | 1,5,4,3 |
| 2 | 2,6 |
--------------------
I cannot figure out the ordering. My preliminary attempt is:
SELECT clue_id, GROUP_CONCAT(group_id)
FROM [resulting_table]
GROUP BY clue_id
ORDER BY [something]
Any help is appreciated: what queries would fit this scenario?
The first part of your question can be solved this way (it expects that run_order is unique per group):
SELECT t1.group_id,
t1.clue_id AS current_clue
FROM group_clue t1
INNER JOIN (SELECT group_id,
MIN(run_order) as run_order
FROM group_clue
WHERE completed = 0
GROUP BY group_id) t2 USING (group_id, run_order)
The logic of this query is pretty simple:
The inner query selects the pairs of group_id and the corresponding minimal value of run_order which has the completed = 0.
After that we join the original table to this set of pairs so that we could select the corresponding clue_id additionally.
You can sort by number of elements per group using
ORDER BY COUNT(*) DESC

Display 2 filtered columns from 2 tables in PHP

I have 2 tables - users and users_audit, need to display results from 2 separate queries into 2 columns with relation to each other. I already figured out both queries.
query for users: SELECT rowid,data FROM users WHERE columnid = 1 GROUP BY rowid;
+-------+------------+
| rowid | data |
+-------+------------+
| 1 | John |
| 2 | Abi |
| 3 | Tony |
| 4 | Gregg |
| 5 | Jon |
| 6 | Victor |
| 7 | Daniel |
query for users_audit: SELECT date_created FROM users_audit WHERE rowid = 6 ORDER BY date_created DESC, date_created DESC LIMIT 1;
Purpose of the query is to display latest date_created for particular rowid.
+---------------------+
| date_created |
+---------------------+
| 2012-07-04 09:20:12 |
+---------------------+
Table users_audit looks like this:
SELECT * FROM users_audit;
+-------+---------+--------------+-------------+---------------------+
| id | rowid | before_value | after_value | date_created |
+-------+---------+--------------+-------------+---------------------+
| 1 | 6 | 3 | 5 | 2012-06-29 15:48:11 |
| 2 | 5 | Out (0) | 2 | 2012-07-04 09:20:10 |
| 3 | 6 | 5 | 4 | 2012-07-04 09:20:12 |
| 4 | 7 | 3 | 6 | 2012-07-04 09:20:14 |
| 5 | 3 | 2 | 3 | 2012-07-04 09:20:16 |
| 6 | 15 | 6 | 5 | 2012-07-04 09:20:22 |
I need to display 2 columns - data from users and date_created from users_audit for each rowid. It means query for users_audit must be run for each rowid (in the loop?).
Expected result displayed in php is:
+------------+----------------------+
| data | date_created |
+------------+----------------------+
| John | (latest date) |
| Abi | (latest date) |
| Tony | (latest date) |
| Gregg | (latest date) |
| Jon | (latest date) |
| Victor | 2012-07-04 09:20:12 |
| Daniel | (latest date) |
How can this be achieved this in php?
Why cant you just create a view and use a join to create the table you want?
SELECT users.data, users_audit.date_created FROM users
INNER JOIN users_audit ON users.rowid = users_audit.rowid
Or am I missing something here?
EDIT
SELECT users.data, users_audit.date_created FROM users
INNER JOIN users_audit ON users.rowid = users_audit.rowid
WHERE users_audit.date_created = (SELECT MAX(date_created) from users_audit
GROUP BY rowid)
I believe this should work..? Let me know.

Query union, if search result is less than 10, fill with others from database order by date

I want to make a mysql union search. My purpose is: my total results back must be 10.
if search results are more than 10, the returned data come all from search result.
if search results are less than 10, first few returned data come from search result, and then fetch the remaining results from database order by date.
To make it clearer: if a client searches "today", my database only returns 7 results which contain "today", then add another 3 results from my database ORDER BY date. So that the total results are 10 items.
Another purpose: another 3 results are not repetitions from the 7 results which match the search. I think UNION or UNION DISTINCT can do that job, am I right?
So, how do I do a query like this?
PS: my code will fix the result order, but I need first select is always behind the second select
(SELECT * FROM table WHERE title like %$searchword% limit 0,10 ORDER BY date)
UNION
(SELECT * FROM table limit 0,10 ORDER BY date)
limit 0,10 ORDER BY date
If you always want 10 results:
SELECT
IF(m.id,1,0) AS has_match,
t.*
FROM
`table` t
LEFT JOIN `table` m ON m.id = t.id AND m.title LIKE '%$searchword%'
GROUP BY t.id
ORDER BY has_match DESC, date
LIMIT 10
Tested:
mysql> select * from `table`;
+----+------------------------+---------------------+
| id | title | date |
+----+------------------------+---------------------+
| 1 | test 1 | 2011-11-06 10:27:08 |
| 2 | test 2 match | 2011-11-06 10:27:14 |
| 3 | 3 match this too | 2011-11-06 10:27:23 |
| 4 | title does NOT | 2011-11-06 10:27:44 |
| 5 | Another matching title | 2011-11-06 10:27:55 |
| 6 | this does not either | 2011-11-06 10:29:22 |
| 7 | Do not put this first | 2011-11-06 10:29:37 |
| 8 | Is this number 8? | 2011-11-06 10:29:57 |
| 9 | The 9th is a match | 2011-11-06 10:30:07 |
| 10 | 10th does not | 2011-11-06 10:30:20 |
| 11 | 11th IS a match too! | 2011-11-06 10:30:37 |
| 12 | 12th gets ignored? | 2011-11-06 10:30:49 |
+----+------------------------+---------------------+
12 rows in set (0.00 sec)
mysql> SELECT IF(m.id,1,0) AS has_match, t.* FROM `table` t LEFT JOIN `table` m ON m.id = t.id AND m.title LIKE '%match%' GROUP BY t.id ORDER BY has_match DESC, date LIMIT 10;
+-----------+----+------------------------+---------------------+
| has_match | id | title | date |
+-----------+----+------------------------+---------------------+
| 1 | 2 | test 2 match | 2011-11-06 10:27:14 |
| 1 | 3 | 3 match this too | 2011-11-06 10:27:23 |
| 1 | 5 | Another matching title | 2011-11-06 10:27:55 |
| 1 | 9 | The 9th is a match | 2011-11-06 10:30:07 |
| 1 | 11 | 11th IS a match too! | 2011-11-06 10:30:37 |
| 0 | 1 | test 1 | 2011-11-06 10:27:08 |
| 0 | 4 | title does NOT | 2011-11-06 10:27:44 |
| 0 | 6 | this does not either | 2011-11-06 10:29:22 |
| 0 | 7 | Do not put this first | 2011-11-06 10:29:37 |
| 0 | 8 | Is this number 8? | 2011-11-06 10:29:57 |
+-----------+----+------------------------+---------------------+
10 rows in set (0.00 sec)

Categories