SQL not ordering correctly by time - sql

$sql = "SELECT * FROM messages WHERE (from_user = :from_user AND to_user = :to_user) OR
(from_user = :fromuser AND to_user = :touser) ORDER BY time ASC";
after sometime the messages are not appropriately shown based on time.
They mix it self, can somebody help?
my php time format $time = date('d-m-Y G:i:s');

As people have said in the comments, it's better to have the correct datatypes in your table. But such is life, if you aren't the DBA and have to work with this string data, you can use the STR_TO_DATE() function.
$sql = "SELECT * FROM messages WHERE (from_user = :from_user AND to_user = :to_user) OR (from_user = :fromuser AND to_user = :touser) ORDER BY STR_TO_DATE(time,'%d-%m-%Y %H:%i:%s') ASC";

Related

query_exec(SELECT * FROM myTable) fails on pyqt5

i have a function like below
def updateExpenseEntryToDb (self):
self.day = self.line_edit1.text()
self.category = self.line_edit2.text()
self.amount = self.line_edit3.text()
db = QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('expenses.db')
db.open()
query = QSqlQuery()
query.exec_("create table expense(date DATE primary key, "
"category varchar(20), amount varchar(20))")
query.exec_("insert into expense (date,category,amount) values('%s','%s','%s')" % (self.day, self.category, self.amount))
db.close()
db1 = QSqlDatabase.addDatabase('QSQLITE')
db1.setDatabaseName('expenses.db')
db1.open()
query1 = QSqlQuery()
query1.exec_("SELECT date, category, amount FROM expenses.expense")
while (query1.next()):
extractedDate = query1.value(0).toString()
extractedcategory = query1.value(1).toString()
extractedAmount = query1.value(2).toString()
self.line_edit1.setText(extractedDate)
self.line_edit2.setText(extractedcategory)
self.line_edit3.setText(extractedAmount)
db1.close()
Insertion of values into DB works but not the retrieval of info from DB. What am i doing wrong ? seems like select query doesnt retrieve anything at all
Put query.first() before while (query1.next()): But, the first row won't be used.
Better:
query.first()
while query.isValid():
# Your Code
query.next()

How to Join two tables showing all records Where Table A is Not In Table B

I have a email marketing web application. I want to show which email contacts in (Table B) are not showing up in EmailContacts_Campaign (Table A). In addition, I want to filter table A by the CampaignId field. When I run the below code I get 0 records, yet I know there are a couple of thousand records there. Can anyone tell me where I am messing up?
SELECT * FROM TableA
LEFT JOIN TableB
ON TableA.EmailContactId = TableB.EmailContactId
WHERE TableA.CampaignId = 1
AND TableB.EmailContactId IS NULL
ORDER BY TableB.EmailContactId DESC
I want to show all email contacts in the EmailContact Table that are not showing up in the EmailContactCampaign table. Here is the actual code:
public List<EmailContact> GetNotAssignedContactsForCampaign(int campaignId)
{
string sqlCommand = "SELECT * FROM EmailContactCampaign LEFT JOIN EmailContact";
sqlCommand += " ON EmailContactCampaign.EmailContact_EmailContactId = EmailContact.EmailContactId";
sqlCommand += " WHERE EmailContactCampaign.EmailContact_EmailContactId = " + campaignId.ToString() AND EmailContact.EmailContactId IS NULL ;
sqlCommand += " ORDER BY EmailContact.EmailContactId DESC";
var emailContacts = new List<EmailContact>();
string CS = db.Database.Connection.ConnectionString;
using (SqlConnection con = new SqlConnection(CS))
{
con.Open();
SqlCommand cmd = new SqlCommand(sqlCommand, con);
//Create sql datareader
using (SqlDataReader sqlDataReader = cmd.ExecuteReader())
{
while (sqlDataReader.Read())
{
var emailContact = new EmailContact();
emailContact.Assigned = ((bool)sqlDataReader["Assigned"]);
emailContact.Cell1 = _crypto.DecryptAndSanitize(sqlDataReader["Cell1"] as string);
emailContact.Cell2 = _crypto.DecryptAndSanitize(sqlDataReader["Cell2"] as string);
emailContact.City = _crypto.DecryptAndSanitize(sqlDataReader["City"] as string);
emailContact.Company = _crypto.DecryptAndSanitize(sqlDataReader["Company"] as string);
emailContact.EmailAddress = _crypto.DecryptAndSanitize(sqlDataReader["EmailAddress"] as string);
emailContact.EmailContactId = (int)sqlDataReader["EmailContactId"];
emailContact.FullName = _crypto.DecryptAndSanitize(sqlDataReader["FullName"] as string);
emailContact.Hold = (bool)sqlDataReader["Hold"];
emailContact.Phone1 = _crypto.DecryptAndSanitize(sqlDataReader["Phone1"] as string);
emailContact.Phone2 = _crypto.DecryptAndSanitize(sqlDataReader["Phone2"] as string);
emailContact.State = _crypto.DecryptAndSanitize(sqlDataReader["State"] as string);
emailContact.Status = (Status)sqlDataReader["Status"];
emailContact.Zip = _crypto.DecryptAndSanitize(sqlDataReader["Zip"] as string);
emailContacts.Add(emailContact);
}
}
return (emailContacts);
}
}
Have you tried this?
SELECT * FROM tableB WHERE EmailContactId NOT IN (SELECT EmailContactId FROM tableA)
i think you got 0 probably because of this AND TableB.EmailContactId IS NULL
Please try this one
SELECT * FROM TableA
LEFT JOIN TableB
ON TableA.EmailContactId = TableB.EmailContactId
WHERE TableA.CampaignId = 1
ORDER BY TableB.EmailContactId DESC
I'm sorry my question was not clear enough. Did some digging and found the answer on another post. Sorry but I accidentally closed it and can't find it again. Anyway, here is my implementation of it.
SELECT * FROM EmailContact
WHERE NOT EXISTS
(SELECT * FROM EmailContactCampaign WHERE EmailContactCampaign.EmailContact_EmailContactId = EmailContact.EmailContactId AND EmailContactCampaign.Campaign_CampaignId = 1)
If i understood your question correctly, you are looking for B's that are not in A. But your query will return A's that are not in B. Turn it aroung (tableB left join tableA where a... is NULL)
Your problem was that you had it the wrong way around: your query would return all contacts from EmailContactCampaign that were not in EmailContact.
The correct solution for your problem would look like this:
SELECT * FROM EmailContact
WHERE EmailContactId NOT IN (
SELECT EmailContact_EmailContactId FROM EmailContactCampaign
WHERE Campaign_CampaignId = ?
)
ORDER BY EmailContact.EmailContactId DESC

My first attempt at PDO statements - Is this code actually correct and doing what it should?

I'm brand new to PDO statements, and this is my very first attempt.
I'm not completely sure if the code I have produced is achieving anything?
Am I protected from coding-genius-hackers?
<?php
$host = "localhost";
$db = "test";
$user = "root";
$pass = "admin";
$who = '65';
$conn = new PDO("mysql:host=$host;dbname=$db",$user,$pass);
$sql = "SELECT
tbl_tracking.id as trackID,
tbl_tracking.from_user as trackFROM,
tbl_tracking.viewed as trackVIEWED,
tbl_tracking.date as trackDATE,
tbl_users.id as usrID,
tbl_users.name as usrNAME,
tbl_photos.profile as photosPROFILE,
tbl_photos.photo_link as photoLINK,
tbl_photos.default_photo as photoDEFAULT
FROM tbl_tracking
LEFT JOIN tbl_users ON tbl_tracking.from_user = tbl_users.id
LEFT JOIN tbl_photos ON tbl_photos.profile = tbl_users.id
WHERE tbl_tracking.viewed = '$who' AND tbl_photos.default_photo IS NULL OR tbl_photos.default_photo = '1'
GROUP BY tbl_tracking.from_user
ORDER BY tbl_tracking.id DESC
LIMIT 9
";
$q = $conn->query($sql) or die("failed!");
while($r = $q->fetch(PDO::FETCH_ASSOC)){
echo '<img src="../assets/uploads/thumbnail_' . $r['photoLINK'] . '" class="suggestUser" />';
}
?>
To be protected against sql injection, you must use PDO's new of verifying values: binding parameters. This needs that your prepare statements instead of running them directly:
$q = $conn->prepare($sql); // the default way of PDO to manage errors is quite the same as `or die()` so no need for that
Change your where clause:
WHERE tbl_tracking.viewed = :who AND tbl_photos.default_photo IS NULL OR tbl_photos.default_photo = '1'
then bind the value to your statement and execute it:
$q->bindValue(':who',$who,PDO::PARAM_INT);
$q->execute();
or you can execute it directly with an array of values:
$q->execute(array(':who' => $who));
otherwise, I'm not very sure what your code should be doing, so I can't really tell if it will, but if your sql worked before using PDO, it should work now too.
For your code to be prone to sql injection, one of the values in your query must have a way to come from user-input, and it must be passed as-is to PDO's prepare(). Since we use a parameter :who instead of $who, there's no way your sql will be prepared with dangerous values.

How to write the HAVING clause with SQL COUNT(DISTINCT column_name) function in Codeigniter Active Record?

I am using Codeigniter and am trying to use the Active Record Class for all my database operations.
However, I did run into problems when trying to convert the last bid of the following (working) query into Active Record code.
$sql = ("SELECT ac.cou_id
FROM authorcourse ac
INNER JOIN course c
ON ac.cou_id = c.cou_id
WHERE cou_name = ? // ? = $cou_name
AND cou_number = ? // ? = $cou_number
AND cou_term = ? // ? = $cou_term
AND cou_year = ? // ? = $cou_year
AND FIND_IN_SET (ac.aut_id, ?) //? = $aut_ids_string
GROUP BY ac.cou_id
HAVING COUNT(DISTINCT ac.aut_id) = ? //? = $aut_quantity
AND COUNT(DISTINCT ac.aut_id) = (SELECT COUNT(DISTINCT ac2.aut_id)
FROM authorcourse ac2
WHERE ac2.cou_id = ac.cou_id)");
$query = $this->db->query($sql, array($cou_name, $cou_number, $cou_term, $cou_year, $aut_ids_string, $aut_quantity));
Question: How do I convert the HAVING clause into valid Active Record code?
I tried using $this->db->having(); and $this->db->distinct(); but failed to combine the functions to achieve the desired result.
My (working) code so far:
$this->db->select('ac.cou_id');
$this->db->from('authorcourse ac');
$this->db->join('course c', 'c.cou_id = ac.cou_id');
$this->db->where('cou_name', $cou_name);
$this->db->where('cou_number', $cou_number);
$this->db->where('cou_term', $cou_term);
$this->db->where('cou_year', $cou_year);
$this->db->where_in('ac.aut_id',$aut_ids);
$this->db->group_by('ac.cou_id');
// missing code
Thanks a lot!
You code seems quite clumsy. But, you can use having clause in the following way:
$this->db->having("ac.aut_id = '".$aut_qty."'", null, false)

SQL Get UID when Group by

I do a select from table
[V_RPT_BelegungKostenstelleDetail]
WHERE SO_UID = '7C7035C8-56DD-4A44-93CC-F16FD66280A3'
AND GB_UID = '4FF1B0EE-A5DD-4699-94B7-760922666CE2'
AND GS_UID = '1188759A-54E1-4323-8BF2-85E71B3C796E'
AND RM_UID = '088C3559-6E6E-468A-9554-6740840FCBA1'
AND NA_UID= '96A2A8DB-8C83-4C60-9060-F0F55719AF5C'
GROUP BY KST_UID
How can I get SO_UID? It is the same everywhere, but I get an error when I try to get SO_UID with the return values...
SO_UID is not necessarely given like '7C7035C8-56DD-4A44-93CC-F16FD66280A3' here, so I can't just add it manually as string.
You need to use an aggregate function to get other column data. As this column will always have the same value (thanks to the WHERE clause), you can use MAX():
SELECT KST_UID, MAX(SO_UID)
FROM [V_RPT_BelegungKostenstelleDetail]
WHERE SO_UID = '7C7035C8-56DD-4A44-93CC-F16FD66280A3'
AND GB_UID = '4FF1B0EE-A5DD-4699-94B7-760922666CE2'
AND GS_UID = '1188759A-54E1-4323-8BF2-85E71B3C796E'
AND RM_UID = '088C3559-6E6E-468A-9554-6740840FCBA1'
AND NA_UID= '96A2A8DB-8C83-4C60-9060-F0F55719AF5C'
GROUP BY KST_UID
The correct answer is as simple as the question is stupid:
SELECT KST_UID, SO_UID, GB_UID, RM_UID, NA_UID
FROM [V_RPT_BelegungKostenstelleDetail]
WHERE SO_UID = '7C7035C8-56DD-4A44-93CC-F16FD66280A3'
AND GB_UID = '4FF1B0EE-A5DD-4699-94B7-760922666CE2'
AND GS_UID = '1188759A-54E1-4323-8BF2-85E71B3C796E'
AND RM_UID = '088C3559-6E6E-468A-9554-6740840FCBA1'
AND NA_UID = '96A2A8DB-8C83-4C60-9060-F0F55719AF5C'
GROUP BY KST_UID, SO_UID, GB_UID, RM_UID, NA_UID