data count from two different table by group by - mysql

i have two table a,b and both tables structure is same as below
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| srno | int(11) | NO | PRI | NULL | auto_increment |
| domain | varchar(50) | NO | UNI | NULL | |
| timestamp | timestamp | YES | | NULL | |
| source | varchar(100) | YES | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
i want domain count from both table on particular date
so plz help

I think the tricky part of the question is that you need union all to bring the tables together. The rest of the question is unclear. If I interpret it as getting all domains with their counts on one particular day:
select domain, count(*)
from ((select a.* from a) union all
(select b.* from b)
) ab
where timestamp >= $YOURDATE and
timestamp < date_add($YOURDATE, interval 1 day)
group by domain;
Note: Having two tables with exactly the same structure is usually a sign of poor database design. A single entity is usually placed in a single table. More typically, there would be one table with a column specifying "a" or "b".

Related

MySQL solution for grouped images?

i am looking for someone who can help me to achieve a way to store multiple images as a group in mysql.
Basically a user will upload multiple images for example 3 as a group (1 POST), how can i store them in the database.
This is how i store images right now.
+-------------+------------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+-------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| userid | int(11) | NO | | NULL | |
| uploaded_at | datetime | YES | | CURRENT_TIMESTAMP | |
| path | varchar(255) | NO | | NULL | |
| is_grouped | int(11) | YES | | 0 | |
| grouped_to | int(11) | YES | | 0 | |
+-------------+------------------+------+-----+-------------------+----------------+
'is_grouped' ( 0 or 1 ) & 'grouped_to' ( id of main image ) are what i though could work but caused problems while retrieving from mysql database.
Any help would be appreciated.
I don't know what exact problem you are having with your current approach, but I would suggest just using the following definition for the images table:
images (id, user_id, uploaded_at, path)
Then, create a junction table which relates images to their groups:
image_groups (image_id, group_id)
We don't really need the is_grouped column any more, because we can simply check image_groups to see if the image appears in a group and/or if that group has more than one image. Similarly, the grouped_to column has now been made redundant because the junction table stores this information. Note that you might also want to have a groups table, which could store some metadata about each image group, such as the name, time of creation, etc.

Select the most recent note/comment from an application [duplicate]

This question already has answers here:
SQL select only rows with max value on a column [duplicate]
(27 answers)
Closed 5 years ago.
I have 2 relevant tables here, application and application_note.
I want to find the latest note (user and text/note) for each application.
application_note looks like
+----------------+-------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| create_time | timestamp | NO | | CURRENT_TIMESTAMP | |
| update_time | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| application_id | int(11) | YES | MUL | NULL | |
| note | text | YES | | NULL | |
| user | varchar(50) | YES | | NULL | |
+----------------+-------------+------+-----+-------------------+-----------------------------+
I've been trying a bunch of different queries. The closest thing I have is
SELECT user, note, application_id, MAX(create_time)
FROM application_note
GROUP BY application_id
which looks like the max(create_time) is what I expect, but the other values are off. I've been trying at this for awhile and have been getting no where.
edit: I plan to eventually add this a view or add this to a larger query, if that changes anything.
You have to join the table back on itself:
SELECT b.application_id, b.ct, a.note, a.user
FROM (SELECT application_id, MAX(create_time) AS ct
FROM application_note
GROUP BY application_id) b
INNER JOIN application_note a ON a.application_id=b.application_id
AND a.create_time=b.ct
This will return the record with the latest creation time for a given application id. Duplicates might occur when you have multiple records with the same creation_time for a given application_id

MYSQL need AVERAGE from one table based on information from second table

I'm slowly teaching myself MySQL methods, and I'm having a tough time with this. I haven't even been able to figure out HOW to Google the question.
I have the following two tables (I think my data is normalized, but suggestions welcome):
Table 1
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| rate_id | int(11) | NO | PRI | NULL | auto_increment |
| rate | decimal(9,2) | YES | | NULL | |
| guess | decimal(9,2) | YES | | NULL | |
| date | date | YES | MUL | NULL | |
| house_id | int(11) | NO | MUL | NULL | |
| date_mod | date | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
Table 2
+-----------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(64) | YES | | NULL | |
| beds | int(2) | YES | | NULL | |
| baths | int(2) | YES | | NULL | |
| pets | char(4) | YES | | NULL | |
| pool | char(4) | YES | | NULL | |
+-----------------+---------------+------+-----+---------+----------------+
I want to populate guess with the average rate of all properties during the same date period, based on similar properties in table 2. That is, for each id/house_id, I need all the houses that are similar (same beds, baths, view, etc.), and then the average of all the rates on the same dates.
My biggest issue is that I don't understand how to reference a field in a second table based on the id selected. This is what I'm starting with - just to see if I can get averages to return (I know this won't UPDATE the guess field).
SELECT AVG(t1.rate)
INNER JOIN t2 ON (t1.house_id = t2.id)
WHERE t2.beds = t2.beds
AND t2.baths = t2.baths
AND t2.pets = t2.pets
AND t1.date = t1.date
AND t1.house_id = 2;
Aside from the fact that the SQL command doesn't complete - I think it's obvious that my SQL knowledge is woefully inadequate - I think I'm just missing a more complex SQL method to identify the fields I'm looking for. Can anybody help?
#Strawberry - appreciate the comments. As it turns out, I already had AVG() working (I had already Googled it)
My problems were in two sets. First, how does one get column values from one table to use to get keys for us on another table. I didn't realize that you could use a nested SELECT statement to do this - although I still haven't convinced myself this is the most efficient way to do this.
Second, the average function was grouping all rates together into one average. I was able to do a bit of manipulation to produce the output I was looking for, but ultimately, the GROUP BY function was able to provide me most of the functionality I needed. Below is basically what I ended up with.
SELECT date, AVG(t1.rate) FROM rates
JOIN houses ON (t1.house_id = t2.id)
WHERE beds = (SELECT beds FROM t2 WHERE id = 2)
AND baths = (SELECT baths FROM t2 WHERE id = 2)
AND pets = (SELECT pets FROM t2 WHERE id = 2)
GROUP BY date;
Thanks for commenting.

MYSQL query return empty result

I need to look up email preferences for users.
This table contains the types of email a user can receive, broken down by category.
email_preferences_categories
+----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | text | YES | | NULL | |
| overview | text | YES | | NULL | |
+----------+------------------+------+-----+---------+----------------+
This table contains their preference for receiving various types. If they haven't set their preferences, this table won't have any rows for them.
email_preferences
+------------+---------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| user_id | int(10) unsigned | NO | | NULL | |
| name | text | YES | | NULL | |
| frequency | enum('Daily','Monthly','None') | YES | | Daily | |
+------------+---------------------------------+------+-----+---------+----------------+
I need to construct a MYSQL query that returns the name and frequency corresponding to the email preferences for a given user.
SELECT name, frequency
FROM email_preferences
LEFT JOIN email_preferences_categories using (name)
WHERE user_id = 42
Where I'm having trouble: If the user hasn't set their preferences, this query doesn't return any rows. I would like it to return the default of 'Daily' for email categories that are missing.
Change LEFT JOIN to RIGHT JOIN.
...
FROM email_preferences
RIGHT JOIN email_preferences_categories
...
Or alternatively you can swap the tables around:
...
FROM email_preferences_categories
LEFT JOIN email_preferences
...
These two options both do the same thing - ensure that you get all rows from email_preferences_categories even if there is no matching row in email_preferences.
You also need to change the join condition as you already noticed.
I would like it to return the default of 'Daily' for email categories that are missing.
You can use IFNULL:
SELECT name, IFNULL(frequency, 'Daily') AS frequency
This query doesn't need a WHERE clause. It needs a more restrictive JOIN. Here is the full query combined with Mark Byers answer above.
SELECT email_preferences_categories.name, IFNULL(frequency, 'Daily') AS frequency
FROM email_preferences_categories
LEFT JOIN email_preferences
ON email_preferences.name = email_preferences_categories.name
AND user_id = 42;

Query to count how many times an ip is used with different accounts

I would like a single query to count how many different customer accounts use the same IP to log in.
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| info_id | int(11) | NO | PRI | NULL | auto_increment |
| afid | int(11) | NO | | 0 | |
| access | date | NO | | NULL | |
| ip | varchar(15) | NO | | | |
+---------+-------------+------+-----+---------+----------------+
afid is the customer id. Every time they log in a row is inserted into this table. I have been trying nested selects without any luck, and anything I can think of. I'm probably over thinking this too much :)
Thanks in advance!
Try this:
SELECT COUNT(DISTINCT afid) AS afid_count
FROM yourtable
WHERE ip = '....'
To get a list of the most frequently used IPs:
SELECT
ip,
COUNT(DISTINCT afid) AS afid_count
FROM yourtable
GROUP BY ip
HAVING afid_count > 1
ORDER BY afid_count DESC