Query Construction Combining UNION and LEAST - mysql

I have an email subscription table and a user table. I need to combine the two to get all the emails, since it's possible to create an account without subscribing and vice versa. Easy enough so far:
SELECT email FROM emailcapture
UNION
SELECT email FROM cpnc_User
Now, this gets me the complete list of all emails. For each email on this combined list, I need to add an extra piece of information: the created date. Both emailcapture and cpnc_User tables have a "created" field. The created date should be the earlier of the two dates, if both dates exist, or, if only one exists and the other is NULL, it should just be the one that exists.
How can I change this query so that it returns this extra piece of information, the created date? Keep in mind that the new query I seek should return exactly the same number of rows as the query above.
Thanks,
Jonah

SELECT i.email, MIN(i.date_creation) FROM
(SELECT email, date_creation FROM emailcapture
UNION ALL
SELECT email, date_creation FROM cpnc_User) as InnerTable i
GROUP BY i.email

Related

Mysql Where IN (query) doesn't work. here, query gives a string(example: 1,2,3) [duplicate]

i have 2 tables customers and imap_emails. customer table contain emails of customers.
I am using PHP-IMAP to fetch email from email server and then saving to database table imap_emails.
the imap_emails table has 2 fields from and to and to field contains comma separated values.
i need to fetch emails from first table and then search against to and from on imap_emails.
First i thought about a LIKE condition to search , but i would like to have something like FIND_IN_SET or something other.
How can i achieve this in a better way ? ( For some reasons i cannot use relations on this table )
Please advice.
Example of doing a join based on FIND_IN_SET
SELECT *
FROM imap_emails
INNER JOIN customers
ON FIND_IN_SET(customers.email, imap_emails.to) > 0
You don't say how you want to narrow this down (ie, if an email uses 2 email addresses do you want both emails brought back), so can't add much at this stage.

mysql query using column values as parameter in query phpMyAdmin

I have a query i have been working on trying to get a specific set of data, join the comments in duplicate phone numbers of said data, then join separate tables based on a common field "entry_id" which also happens to be the number on the end of the word custom_ to pull up that table.
table named list and tables containing the values i want to join is custom_entry_id (with entry_id being a field in list in which i need the values of each record to replace the words in order to pull up that specific table) i need entry_id from the beginning part of my query to stick onto the end of the word custom for every value my search returns to get the fields from that custom table designated for that record. so it will have to do some sort of loop i guess? sorry like i said I am at a loss at this point
this is where i am so far:
SELECT * ,
group_concat(comments SEPARATOR '\r\n\r\n') AS comments_combined
FROM list WHERE `status` IN ("SALEA","SALE")
GROUP BY phone_number
//entry_id is included in the * as well as status
// group concat combines the comments if numbers are same
i have also experimented on test data with doing a full outer join which doesnt really exist. i feel if you can solve the other part for me i can do the joining of the data with a query similar to this.
SELECT * FROM test
LEFT JOIN custom_sally ON test.num = custom_sally.num
UNION
SELECT * FROM test
RIGHT JOIN custom_sally ON test.num = custom_sally.num
i would like all of this to appear with every field from my list table in addition to all the fields in the custom_'entry_id' tables for each specific record. I am ok with values being null for records that have different custom fields. so if record 1 has custom fields after the join of hats and trousers and record 2 has socks and shoes i realize that socks and shoes for record 1 will be null and hats and trousers for record 2 will be null.
i am doing all this in phpmyadmin under the SQL tab.
if that is a mistake please advise as well. i am using it because ive only been working with SQl for a few months. from what i read its the rookie tool.
i might be going about this all wrong if so please advise
an example
i query list with my query i get 20,000 rows with columns like status, phone_number, comments, entry_id, name, address, so on.
now i want to join this query with custom fields in another table.
the problem is the custom tables' names are all linked to the entry_id.
so if entry_id is 777 then the custom table fields are custom_777
my database has over 100 custom tables with specials fields for each record depending on its entry_id.
when i query the records I don't know how to join the custom fields that are entry_id specific to the rest of my data.i will pull up some tables and data for a better example
this is the list table:
this is the custom_"entry_id"
Full Outer Join in MySQL
for info on full outer joins.

Pulling different records from multiple tables as one transaction history list

I am working on an employee management/reward system and need to be able to show a single "transaction history" page that shows in chronological order the different events that the employee has experienced in one list. (Sort of like how in facebook you can goto your history/action section and see a chronological list of all the stuff that you have done and affects you, even though they are unrelated to eachother and just have you as a common user)
I have different tables for the different events, each table has an employee_id key and an "occured" timestamp, some table examples:
bonuses
customers
raise
complaints
feedback
So whenever an event occurs (ie a new customer is assigned to the employee, or the employee gets a complaint or raise) a new row is added to the appropriate table with the employee ID it affects and a timestamp of when it occured.
I need a single query to pull all records (upto 50 for example) that include the employee and return a history view of that employee. The field names are different in each table (ie the bonus includes an amount with a note, the customer includes customer info etc).
I need the output to be a summary view using column names such as:
event_type = (new customer, bonus, feedback etc)
date
title (a brief worded title of the type of event, specified in sql based on the table its referencing)
description (verbiage about the action, such as if its event_type bonus display the bonus amount here, if its a complain show the first 50 characters of the complaint message or the ID of the user that filed the complaint from the complaints table. All done in SQL using if statements and building the value of this field output based on which table it comes from. Such as if its from the customers table IF current_table=customers description='A customer was assigned to you by'.customers.assigner_id).
Ideally,
Is there any way to do this?
Another option I have considered, is I could do 5-6 different queries pulling the records each from their own table, then use a mysql command to "mesh/interleave" the results from all the queries into one list by chronological order. That would be acceptable too
You could use a UNION query to merge all the information together and use the ORDER BY clause to order the actions chronologically. Each query must have the same number of fields. Your ORDER BY clause should be last.
The examples below assume you have a field called customer_name in the customers table and bonus_amount in the bonuses table.
It would look something like this:
SELECT 'New Customer' as event_type, date,
'New customer was assigned' as title,
CONCAT('New Customer: ', customer_name, ' was assigned') as description
FROM customers
WHERE employee_id = 1
UNION
SELECT 'Bonus' as event_type, date,
'Received a bonue' as title,
CONCAT('Received a bonus of $', FORMAT(bonus_amount, 2), '.') as description
FROM bonuses
WHERE employee_id = 1
UNION
...
ORDER BY date DESC;

SQL deduping help?

I'm sure there are a ton of ways to do this, but right now I'm struggling to find the way that will work properly given the data.
I basically have a table containing duplicates which have additional fields tied to them and source details that take priority over others. So basically I added a "priority" field to my table which I then updated based on source priority. I now need to select the distinct records to populate my "unique" records table (which I'll then apply unique key constraint to prevent this from happening again on the field required!)....
So I have basically, something like this:
Select phone, carrier, src, priority
from dbo.mytable
So basically I need to pull distinct on phone in order of priority (1,2,3,4, etc), and basically pull the rest of the other data along with it and still keep UNIQUE on phone.
I've tried a few things using sub-select from the same table with min(priority) value, but outcome still doesn't seem to make sense. Any help would be greatly appreciated. Thanks!
EDIT I need to dedupe from the same table, but I can populate a new table with the uniques if needed based on my select statement to pull the uniques. This is in MSSQL, but figured anyone with SQL knowledge could answer.
For example, let's say I have the following rows:
5556667777, ATT, source1, 1
5556667777, ATT, source2, 2
5556667777, ATT, source3, 3
I need to pull uniques based on priority 1 first..... the problem is, I need to remove any all other dupes from the table based on the priority order without ending up with the same phone number twice again. Make sense?
So you're saying the combination (phone, priority) is unique in the existing table, and you want to select the rows for which the priority is smallest?
SELECT mytable.phone, mytable.carrier, mytable.src
FROM mytable
INNER JOIN (
SELECT phone, MIN(priority) AS minpriority
FROM mytable
GROUP BY phone
) AS minphone
ON mytable.phone = minphone.phone
AND mytable.priority = minphone.minpriority

How do I select a record from one table in a mySQL database, based on the existence of data in a second?

Please forgive my ignorance here. SQL is decidedly one of the biggest "gaps" in my education that I'm working on correcting, come October. Here's the scenario:
I have two tables in a DB that I need to access certain data from. One is users, and the other is conversation_log. The basic structure is outlined below:
users:
id (INT)
name (TXT)
conversation_log
userid (INT) // same value as id in users - actually the only field in this table I want to check
input (TXT)
response (TXT)
(note that I'm only listing the structure for the fields that are {or could be} relevant to the current challenge)
What I want to do is return a list of names from the users table that have at least one record in the conversation_log table. Currently, I'm doing this with two separate SQL statements, with the one that checks for records in conversation_log being called hundreds, if not thousands of times, once for each userid, just to see if records exist for that id.
Currently, the two SQL statements are as follows:
select id from users where 1; (gets the list of userid values for the next query)
select id from conversation_log where userid = $userId limit 1; (checks for existing records)
Right now I have 4,000+ users listed in the users table. I'm sure that you can imagine just how long this method takes. I know there's an easier, more efficient way to do this, but being self-taught, this is something that I have yet to learn. Any help would be greatly appreciated.
You have to do what is called a 'Join'. This, um, joins the rows of two tables together based on values they have in common.
See if this makes sense to you:
SELECT DISTINCT users.name
FROM users JOIN conversation_log ON users.id = converation_log.userid
Now JOIN by itself is an "inner join", which means that it will only return rows that both tables have in common. In other words, if a specific conversation_log.userid doesn't exist, it won't return any part of the row, user or conversation log, for that userid.
Also, +1 for having a clearly worded question : )
EDIT: I added a "DISTINCT", which means to filter out all of the duplicates. If a user appeared in more than one conversation_log row, and you didn't have DISTINCT, you would get the user's name more than once. This is because JOIN does a cartesian product, or does every possible combination of rows from each table that match your JOIN ON criteria.
Something like this:
SELECT *
FROM users
WHERE EXISTS (
SELECT *
FROM conversation_log
WHERE users.id = conversation_log.userid
)
In plain English: select every row from users, such that there is at least one row from conversation_log with the matching userid.
What you need to read is JOIN syntax.
SELECT count(*), users.name
FROM users left join conversion_log on users.id = conversation_log.userid
Group by users.name
You could add at the end if you wanted
HAVING count(*) > 0

Categories