querying multiple tables order by time in tables - mysql

Actually I am stuck in middle of some mysql code. Can anyone suggest a simple question. I have 6-10 (multiple) tables in a database all having different data means not related to each other.
There is no relation between tables, but have posted time inserted in each of the columns of all the tables. All I want is query all the tables sorted by timed column.
Eg:
table1:
recipename | cook | timetocook | dated (auto posted time - php time())
-----------+------+------------+------
abc | def | 100 | 10
zxy | orp | 102 | 16
table2:
bookname | author | dated (auto posted time - php time())
---------+--------+------
ab | cd | 11
ef | nm | 14
As you can see there is no relation between the table (I have read about joins), I want to show data one by one according to the posted time asc to desc.
like this:
abc def 100 10
ab cd 11
ef nm 14
zxy orp 102 16
So any help...to achieve this ???

SELECT recipename, cook, timetocook, dated
FROM table1
UNION
SELECT bookname, author, dated, NULL
FROM table2
ORDER BY dated
You have to add NULL value to make sure the column counts is the same the order tables.

Related

Joining multiple tables SQL

The following query matches userID's to eachother based off of total score difference. I have two tables, survey & users.
I need to join this to the users table that I have that has usernames/photo links.
The columns I need displayed are users.name & users.photo. All tables currently have a unique userID, which is users.id, and survey.id that helps match users across DB's.
Could anyone give me a hand as how I could get this done? I've been having a lot of trouble figuring this out, thanks in advance.
select a.id yourId,
b.id matchId,
abs(a.q1 - b.q1) + abs(a.q2 - b.q2) + abs(a.q3 - b.q3)+ abs(a.q4 - b.q4)+
abs(a.q5 - b.q5)+ abs(a.q6 - b.q6)+ abs(a.q7 - b.q7)+ abs(a.q8 - b.q8)+
abs(a.q9 - b.q9)+ abs(a.q10 - b.q10) scorediff
from surveys as a
inner join surveys as b on a.id != b.id
WHERE a.id=1
order by scorediff asc
Currently this is the results of that query:
| yourID| matchID| scoreDiff|
----------------------------
| 5 | 2 | 14 |
| 5 | 3 | 25 |
| 5 | 1 | 33 |
| 5 | 6 | 34 |
I would like this as the result:
| yourID| matchID| scoreDiff| name | photo |
----------------------------------------------
| 5 | 2 | 14 | john | url
| 5 | 3 | 25 | steve| url
| 5 | 1 | 33 | jane | url
| 5 | 6 | 34 | kelly| url
matchID can be matched to the users.ID column, as they are all unique to the user.
add a new column with a foreign key constraint
ALTER TABLE surveys
ADD COLUMN id_user REFERENCES user(id);
or the opposite if that's what you want. Not sure if that is mysql syntax.
you can then join the tables via
WHERE u.id = s.id_user
This should (also) be a comment, but its a bit long.
on a.id != b.id
Given the logic elsewhere, this means you are going to get each combination of "surveys" listed twice. Why not:
on a.id<b.id
(note that if there is an index on index.id, this could actually result in the qquery going slower than it would in the absence of an index using both the above join expressions)
abs(a.q1 - b.q1) + abs(a.q2 - b.q2)
so you have multiple values represented as different attributes on the same relation. This is not good. It breaks the rules about normalization and makes your life much more difficult. (and ours).
Also, that you are adding the abs of the difference, to my mind, creates a rather distorted picture of the difference between individuals.
Consider:
user q score
george 1 4
symcbean 1 2
george 2 2
symcbean 2 4
Here, by your calculation there is a difference in score of 4 between the 2 users - but I would have interpreted the data above as meaning that the two users had the same score. Is that really what you intended?

Skipping row for each unique column value

I have a table from which I would like to extract all of the column values for all rows. However, the query needs to be able to skip the first entry for each unique value of id_customer. It can be assumed that there will always be at least two rows containing the same id_customer.
I've compiled some sample data which can be found here: http://sqlfiddle.com/#!9/c85b73/1
The results I would like to achieve are something like this:
id_customer | id_cart | date
----------- | ------- | -------------------
1 | 102 | 2017-11-12 12:41:16
2 | 104 | 2015-09-04 17:23:54
2 | 105 | 2014-06-05 02:43:42
3 | 107 | 2011-12-01 11:32:21
Please let me know if any more information/better explanation is required, I expect it's quiet a niche solution.
One method is:
select c.*
from carts c
where c.date > (select min(c2.date) from carts c2 where c2.id_customer = c.id_customer);
If your data is large, you want an index on carts(id_customer, date).

INSERT data from one table INTO another with the copies (as many as `quantity` field in first table says)

I have an MySQL table creatures:
id | name | base_hp | quantity
--------------------------------
1 | goblin | 5 | 2
2 | elf | 10 | 1
And I want to create creature_instances based on it:
id | name | actual_hp
------------------------
1 | goblin | 5
2 | goblin | 5
3 | elf | 10
The ids of creatures_instances are not important and not relevant to creatures.ids.
How can I make it with just the MySQL in the most optimal (in terms of execution time) way? The single query would be best, but procedure is ok too. I use InnoDB.
I know that with a help of e.g. php I could:
select each row separately,
make for($i=0; $i<line->quantity; $i++) loop in which I insert one row to creatures_instances for each iteration.
The most efficient way is to do everything in SQL. It helps if you have a numbers table. Without one, you can generate the numbers in a subquery. The following works up to 4 copies:
insert into creatures_instances(id, name, actual_hp)
select id, name, base_hp
from creatures c join
(select 1 as n union all select 2 union all select 3 union all select 4
) n
on n.n <= c.quantity;

mysql query displaying incorrect rows

I have a query which currently should only display one row. However it somehow is displaying 4 rows as its result set even though 1) there are only three rows in the table to begin with 2) only one row matches the query criteria.
I am hoping someone might know what I am doing wrong with this MySql query
My database table structure is as below
smsid (int, auto increment), sms_type (text), sms_status (enum 'pending',sent'),
sms_error (test), sms_message(text), sms_mp3file (varchar 50),
sms_sendon (datetime), send_sms_toid (int 5)
My table entries are as so (following the order of the table columns above)
31 | mp3 | pending | | | helloworld.mp3 | 2013-11-20 16:16:00 | 7
30 | text | sent | | hello test | | 2013-11-18 13:12:00 | 8
29 | voice | sent | | testing 123 | | 2013-11-18 10:05:00 | 18
My query is as below
SELECT sms_messages.*, sms_recipients.cust_profid, sms_recipients.sms_cellnumber,
customer_smsnumbers.sms_number, customer_smsnumbers.sms_number
FROM sms_messages, sms_recipients, customer_smsnumbers
WHERE sms_messages.sms_type='mp3' AND sms_messages.sms_sendon <= '2013-11-21'
AND sms_messages.sms_status='pending' AND
sms_messages.send_sms_toid = sms_recipients.smsuser_id
In your query, you have missed a JOINING clause for customer_smsnumbers table. Similar to sms_messages.send_sms_toid = sms_recipients.smsuser_id you need to have a join clause which either connects sms_messages with customer_smsnumbers table or connects sms_recipients with the customer_smsnumbers table.
In the absence of a join clause other (unintended) records are included in the result.

MySQL - COUNT before INSERT in one query

Hey all, I am looking for a way to query my database table only once in order to add an item and also to check what last item count was so that i can use the next number.
strSQL = "SELECT * FROM productr"
After that code above, i add a few product values to a record like so:
ID | Product | Price | Description | Qty | DateSold | gcCode
--------------------------------------------------------------------------
5 | The Name 1 | 5.22 | Description 1 | 2 | 09/15/10 | na
6 | The Name 2 | 15.55 | Description 2 | 1 | 09/15/10 | 05648755
7 | The Name 3 | 1.10 | Description 3 | 1 | 09/15/10 | na
8 | The Name 4 | 0.24 | Description 4 | 21 | 09/15/10 | 658140
i need to count how many times it sees gcCode <> 'na' so that i can add a 1 so it will be unique. Currently i do not know how to do this without opening another database inside this one and doing something like this:
strSQL2 = "SELECT COUNT(gcCode) as gcCount FROM productr WHERE gcCode <> 'na'
But like i said above, i do not want to have to open another database query just to get a count.
Any help would be great! Thanks! :o)
There's no need to do everything in one query. If you're using InnoDB as a storage engine, you could wrap your COUNT query and your INSERT command in a single transaction to guarantee atomicity.
In addition, you should probably use NULL instead of na for fields with unknown or missing values.
They're two queries; one is a subset of the other which means getting what you want in a single query will be a hack I don't recommend:
SELECT p.*,
(SELECT COUNT(*)
FROM PRODUCTR
WHERE gccode != 'na') AS gcCount
FROM PRODUCTR p
This will return all the rows, as it did previously. But it will include an additional column, repeating the gcCount value for every row returned. It works, but it's redundant data...