Cron Bash - select data from two MySQL tables & export to CSV - mysql

I am really bad at creating MySQL queries and need some help. I need to create a bash file to be triggered by a cron job once a week - that queries two tables, grabbing data where the user IDs match in both tables, and adding the select data to a CSV export file. I would like the CSV to be comma separated. Right now the best I can get it tab separated.
My issue in getting this query to run is my syntax (which I know is wrong as I have simply stolen snippets from various articles online). I did get each DB query to work separately (grabbing from one table with one query and another table with another query). Now I need to combine them to grab only the data I need.
Here's my current (non working) query:
#!/bin/bash
mysql -u USERNAME --password=PASSWORD --database=xxxx_DBNAME --execute='SELECT `xxxx_videotraining_user.user_id`, `xxxx_videotraining_user.training_title`, `xxxx_videotraining_user.status`, `xxxx_users.id`, `xxxx_users.name`, `xxxx_users.user_employer`, `xxxx_users.user_ss_number` WHERE `xxxx_videotraining_user.user_id` = `xxxx_users.id` AND `xxxx_videotraining_user.status` = "Completed" AND `xxxx_users.user_ss_number` > "1" ORDER BY `xxxx_videotraining_user.user_id` LIMIT 0, 10000 AND ' -C > /home/xxxx/subs/vtc/DB_EXPORTS/xxxx_videotraining_completed.csv
I think you can see what I am trying to accomplish here - any help would be greatly appreciated!

It also looks like you're missing your FROM clause, have an trailing AND clause (as noted in other answers), and are quoting things incorrectly. This looks to be your original query:
SELECT `xxxx_videotraining_user.user_id`,
`xxxx_videotraining_user.training_title`,
`xxxx_videotraining_user.status`,
`xxxx_users.id`,
`xxxx_users.name`,
`xxxx_users.user_employer`,
`xxxx_users.user_ss_number`
WHERE `xxxx_videotraining_user.user_id` = `xxxx_users.id` AND
`xxxx_videotraining_user.status` = "Completed" AND
`xxxx_users.user_ss_number` > "1"
ORDER BY `xxxx_videotraining_user.user_id`
LIMIT 0, 10000 AND
I think you want to add the FROM clause, quote the table and field separately, and remove the trailing AND, to get something like:
SELECT `xxxx_videotraining_user`.`user_id`,
`xxxx_videotraining_user`.`training_title`,
`xxxx_videotraining_user`.`status`,
`xxxx_users`.`id`,
`xxxx_users`.`name`,
`xxxx_users`.`user_employer`,
`xxxx_users`.`user_ss_number`
FROM `xxxx_users`,
`xxxx_videotraining_user`
WHERE `xxxx_videotraining_user`.`user_id` = `xxxx_users`.`id` AND
`xxxx_videotraining_user`.`status` = "Completed" AND
`xxxx_users`.`user_ss_number` > "1"
ORDER BY `xxxx_videotraining_user`.`user_id`
LIMIT 0, 10000
There are other things that could be done to shorten the size of the query and make it a bit cleaner, but that should get it functional.
One thing I know that helps me when dealing with long queries is to format them like this, with the main clauses separated out so you can see the different sections of the query.
Let me know if that helps.

I think AND shouldn't be here:
LIMIT 0, 10000 AND

Related

Combine multiple rows into one JSON object/array from single MySQL query

I am trying to combine two rows of generated json within mysql, my current code outputs two rows (first is user id, second is the time) I want to combine them into one string. I've explored the use of GROUP CONCAT, JSON_MERGE (and JSON_MERGE_PRESERVE) and also JSON_OBJECTAGG. For further info, I am using MYSQL8.
Current output:
unavailability
{"59745190": "1400"}
{"59745190": "1200"}
My MySQL Script:
SELECT JSON_OBJECT(`appointment_with`, TIME_FORMAT(`appointment_datetime`,'%H%i')) as `unavailability`
FROM `appointments`
WHERE `appointment_with` = '59745190'
AND (DATE(`appointment_datetime`) = '2022-03-30' AND `appointment_confirmed` = 1)
Thank you in advance.

Wordnet MySQL statement doesn't complete

I'm using the Wordnet SQL database from here: http://wnsqlbuilder.sourceforge.net
It's all built fine and users with appropriate privileges have been set.
I'm trying to find synonyms of words and have tried to use the two example statements at the bottom of this page: http://wnsqlbuilder.sourceforge.net/sql-links.html
SELECT synsetid,dest.lemma,SUBSTRING(src.definition FROM 1 FOR 60) FROM wordsXsensesXsynsets AS src INNER JOIN wordsXsensesXsynsets AS dest USING(synsetid) WHERE src.lemma = 'option' AND dest.lemma <> 'option'
SELECT synsetid,lemma,SUBSTRING(definition FROM 1 FOR 60) FROM wordsXsensesXsynsets WHERE synsetid IN ( SELECT synsetid FROM wordsXsensesXsynsets WHERE lemma = 'option') AND lemma <> 'option' ORDER BY synsetid
However, they never complete. At least not in any reasonable amount of time and I have had to cancel all of the queries. All other queries seem to work find and when I break up the second SQL example, I can get the individual parts to work and complete in reasonable times (about 0.40 seconds)
When I try and run the full statement however, the MySQL command line client just hangs.
Is there a problem with this syntax? What is causing it to take so long?
EDIT:
Output of "EXPLAIN SELECT ..."
Output of "EXPLAIN EXTENDED ...; SHOW WARNINGS;"
I did more digging and looking into the various statements used and found the problem was in the IN command.
MySQL repeats the statement for every single row in the database. This is the cause of the hang, as it had to run through hundreds of thousands of records.
My remedy to this was to split the command into two separate database calls first getting the synsets, and then dynamically creating a bound SQL string to look for the words in the synsets.

Results of SQL Query

I am running a SQL query to know the number of times that the same value is on a column.
Query:
SELECT COUNT(CustomerID) AS OrdersFromCustomerID7
FROM Orders
WHERE CustomerID=7;
Query Result:
OrdersFromCustomerID7
---------------------
4
Since I want to put the "4" value to a Linux Environment Variable, I would need to remove the OrdersFromCustomerID7 text from the result. Does anyone know how to accomplish this?
Note: I have already tried removing the AS OrdersFromCustomerID7 from the query and that makes the query result to come like below:
COUNT(CustomerID)
-----------------
4
I need the query result to be returned as a single number since this is afterwards put into an environment variable for future analysis by another script.
Any ideas?
Thank you!
I was finally able to get it to work using the following modifiers in the query:
mysql "DATABASE" -N -s -r "SQL STATEMENT"
-N removes headers
-s removes separator chars
-r raw output
Thank you #Ambrish for your time!

nested "select " query in mysql

hi i am executing nested "select" query in mysql .
the query is
SELECT `btitle` FROM `backlog` WHERE `bid` in (SELECT `abacklog_id` FROM `asprint` WHERE `aid`=184 )
I am not getting expected answer by the above query. If I execute:
SELECT abacklog_id FROM asprint WHERE aid=184
separately
I will get abacklog_id as 42,43,44,45;
So if again I execute:
SELECT `btitle` FROM `backlog` WHERE `bid` in(42,43,44,45)
I will get btitle as scrum1 scrum2 scrum3 msoffice
But if I combine those queries I will get only scrum1 remaining 3 atitle will not get.
You Can Try As Like Following...
SELECT `age_backlog`.`ab_title` FROM `age_backlog` LEFT JOIN `age_sprint` ON `age_backlog`.`ab_id` = `age_sprint`.`as_backlog_id` WHERE `age_sprint`.`as_id` = 184
By using this query you will get result with loop . You will be able to get all result with same by place with comma separated by using IMPLODE function ..
May it will be helpful for you... If you get any error , Please inform me...
What you did is to store comma separated values in age_sprint.as_backlog_id, right?
Your query actually becomes
SELECT `ab_title` FROM `age_backlog` WHERE `ab_id` IN ('42,43,44,45')
Note the ' in the IN() function. You don't get separate numbers, you get one string.
Now, when you do
SELECT CAST('42,43,44,45' AS SIGNED)
which basically is the implicit cast MySQL does, the result is 42. That's why you just get scrum1 as result.
You can search for dozens of answers to this problem here on SO.
You should never ever store comma separated values in a database. It violates the first normal form. In most cases databases are in third normal form or BCNF or even higher. Lower normal forms are just used in some special cases to get the most performance, usually for reporting issues. Not for actually working with data. You want 1 row for every as_backlog_id.
Again, your primary goal should be to get a better database design, not to write some crazy functions to get each comma separated number out of the field.

Mysql is not counting the rows of dates from my php script

I am trying to count the number of dates that occur for a specific mem_id, however, my count output is always "0"... heres my code:
$datechecker = $postdate;
//$postdate is a date variable that is posted via a form into mysql, stored as a DATE
$sql = mysql_query("SELECT * FROM members WHERE mem_id='$id' AND postdate='$datechecker'");
$Counter = mysql_num_rows($sql);
if($Counter >= 0) {
echo "$datechecker $Counter";
exit();
}
This is the output I get: 2011-01-01 0
Even though I have about 10 occurrences of 2011-01-01, so why does my count say "0"? Can anyone help me solve this, or provide an alternate?
echo the string before you mysql_query it, this will validate if the query is what you expect it to be. You can also use count(*) within the query, instead of using php's mysql_num_rows()
I also hope that you're sanitising your input before you're querying that!
1) You didn't clean $postdate, who knows if it conforms to MySQL's definition of DATE?
2) You didn't show us how your members table looks like. Is mem_id primary key? If it is, then of course you're going to get 1 row out of it.
3) You aren't checking whether your query succeeds or not, you immediately pass the resource_id to the mysql_num_rows table - which is a wrong way to perform counting anyway because MySQL (like any other relational database) has inbuilt mechanisms of counting rows based on criteria.
My guess is that your query is failing, seeing there's not $id specified.