Mysql / ignore duplicates on multiple columns - mysql

Afternoon folks
Following on from a previous question,
I have created a small python app that will scrape job postings for me from a website.
I have them saved in a small sql db
Columns are
Job_id / job_title / job company / job_salary / job_location / job_post_date
I was planning on running my script once per day and hoping to ignore duplicate entries.
What sort of query can check against 2 columns I. E. Title and company to make sure it doesn't get inserted again, the date posted will always increment by 1 per day
Python Code
import mysql.connector
import requests
from bs4 import BeautifulSoup
my_db = mysql.connector.connect(
host="192.168.1.1",
user='job_user',
password='job1',
database='job_db'
)
my_cursor = my_db.cursor()
radius = "10"
val1 = input("Enter Job: ")
val2 = input("Enter Location: ")
val3 = input("Enter Radius default:(10): ")
url = "https://www.indeed.co.uk/jobs?q={}&l={}&radius={}".format(val1, val2, val3)
page = requests.get(url)
soup = BeautifulSoup(page.content, 'html.parser')
result1 = soup.find_all(class_="jobsearch-SerpJobCard")
for results in result1:
job = results.find('a', attrs={'data-tn-element': 'jobTitle'})
company = results.find('span', attrs={'class': 'company'})
location = results.find('span', attrs={'class': 'location accessible-contrast-color-location'})
salary = results.find('span', attrs={'class': 'salaryText'})
date_pos = results.find('span', attrs={'class': 'date'})
i1 = job.text.strip()
i2 = company.text.strip()
if location is not None:
i3 = location.text.strip()
else:
i3 = "N/A"
if salary is not None:
i4 = salary.text.strip()
else:
i4 = "N/A"
i5 = date_pos.text.strip()[:1]
print(i1)
print(i2)
print(i3)
print(i4)
print("\n")
sql = "INSERT INTO job_tbl (job_title, job_company, job_salary, job_location, job_posted) \
VALUES (%s, %s, %s, %s, %s)"
val = (i1, i2, i3, i4, i5)
my_cursor.execute(sql, val)
my_db.commit()
SQL Query
+--------+-------------------------------------------------------------------+-------------------------------+----------------+----------------------------+------------+
| job_id | job_title | job_company | job_salary | job_location | job_posted |
+--------+-------------------------------------------------------------------+-------------------------------+----------------+----------------------------+------------+
| 1 | IT Technician | Strathallan School | N/A | £19,000 - £23,000 a year | 3 |
| 2 | English into Romanian IT/Technical Translator (relocation to... | Alpha CRC Ltd. | N/A | £22,000 - £25,000 a year | 7 |
| 3 | IT/Trainee IT Support Analyst | CJ Lang & Son Limited | Dundee DD4 8JU | N/A | 3 |
| 4 | IT Technical Support Apprentice | GP Strategies Training Ltd | Dundee | £10,000 - £12,000 a year | 1 |
| 5 | IT Operations Manager - IRC84524 | Scottish Government | Dundee DD1 | £48,930 - £61,006 a year | 3 |
| 6 | Temporary IT Buyer | brightsolid | Dundee | N/A | 7 |
| 7 | IT Site Support Analyst | Thermo Fisher Scientific | Perth | N/A | 6 |
| 8 | Network and System Administrator | Solutions Driven | Forfar | £30,000 - £35,000 a year | 3 |
| 9 | IT Service Desk Team Leader | Cross Resourcing | Dundee | N/A | 3 |
| 10 | Senior Network Engineer | Raytheon Intelligence & Space | Glenrothes | N/A | 3 |
| 11 | Solutions Architect | NCR | Dundee | N/A | 3 |
| 12 | Technical Support Specialist | The Army | N/A | £15,985 - £20,400 a year | 3 |
| 13 | Pre-Sales Solutions Architect – 12 Month Graduate Internship... | DELL | N/A | N/A | 3 |
+--------+-------------------------------------------------------------------+-------------------------------+----------------+----------------------------+------------+
13 rows in set (0.002 sec)
If I run the same application again it will add the same results, What I want is to match BOTH a Title & Company and check if it has already been added

You would typically put a unique constraint on that tuple of columns, and use update ... on duplicate key when inserting so duplicates are not inserted, but instead the date of the current row is updatedd.
So something like:
create table mytable (
id int primary key auto_increment,
title varchar(50), -- ajust the size as needed
company varchar(50),
salary int,
location varchar(50),
post_date datetime
default current_timestamp, -- not mandatory, but maybe helpful?
unique (title, company)
);
Then:
insert into mytable (title, company, salary, location)
values (?, ?, ?, ?)
on duplicate key update post_date = current_timestamp;

Related

MS Access - Group By and Sum if all values are available query

I am trying to create a query in ms access which sums up costs but want to exclude those that have no value from the result. I am struggling because I want to exclude items from one column based on another column.
I have a column with finished product, column with components that make up finished product, column with quantity of components required for finished product and column with cost for each of components. What I need is to get total cost for each component required and then sum up costs as total cost for finished product which is simple enough.
However there are some blank fields where cost for one or more components are not available, I want those to show in the result with text " Pending " for finished product instead of it summing up only available values.
Below example of what I am trying to do:
BOM_List
What I need in result is below:
BOM_Result
Would really appreciate any help on this :)
Elaborating on June 7ths comment and assuming Table2:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| ID | FinishedProductid | ItemNumber | Component | Uom | ComponentQuantity | ComponentUnit | stdCost |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 1 | 199127402 | 10 | 123123123 | PC | 3 | PC | $1.50 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 2 | 199127402 | 20 | 321321321 | PC | 1 | PC | $2.50 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 3 | 199127402 | 30 | 123456789 | PC | 1 | PC | $3.55 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 4 | 199127402 | 40 | 987654321 | PC | 0.25 | H | $82.00 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 5 | 199127403 | 10 | 111222333 | PC | 3 | PC | $1.50 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 6 | 199127403 | 20 | 333222111 | PC | 1 | PC | |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 7 | 199127403 | 30 | 444555666 | PC | 1 | PC | $3.55 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 8 | 199127403 | 40 | 666555444 | PC | 0.25 | H | $82.00 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'resulting sql to get all FinishedProductids
SELECT Table2.FinishedProductid
FROM Table2
GROUP BY Table2.FinishedProductid;
'once have FinishedProductid's out of the group statement you can just use a calculated variable
SELECT Query2.FinishedProductid, getTotalCost([FinishedProductid]) AS TotalCost
FROM Query2;
'of course a getTotalCost function is needed. Add the following to a code module
Public Function getTotalCost(FinishedProductid As Long) As String
If isPending(FinishedProductid) Then
getTotalCost = "Pending"
Else
getTotalCost = DSum("ComponentQuantity*stdCost", "Table2", "FinishedProductid = " & FinishedProductid)
End If
End Function
Public Function isPending(FinishedProductid) As Boolean
' if any values of stdCost are null set isPending to true
'public functions can be accessed most anywhere in Access
Dim nullCount As Long
nullCount = DCount("ID", "Table2", "FinishedProductid = " & FinishedProductid & " AND ISNULL(stdCost)")
If nullCount > 0 Then
isPending = True
Else
isPending = False
End If
End Function
'result
-------------------------------------------------------
| FinishedProductid | TotalCost |
-------------------------------------------------------
| 199127402 | 31.05 |
-------------------------------------------------------
| 199127403 | Pending |
-------------------------------------------------------
Explanation: I use a two query approach to get around the sql complications that arise from the group by. The functions are relatively declaritive and hence self-commenting. Finally, functions can be reused.
Edit: getTotalCost returns a string so it can meet the requirement of returning both the string "pending" and the total cost

How can I refine this query?

You might want to have a look at my previous question.
My database schema looks like this
--------------- ---------------
| candidate 1 | | candidate 2 |
--------------- \ --------------
/ \ |
------- -------- etc
|job 1| | job 2 |
------- ---------
/ \ / \
--------- --------- --------- --------
|company | | skills | |company | | skills |
--------- --------- ---------- ----------
Here's my database:
mysql> describe jobs;
+--------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------+------+-----+---------+----------------+
| job_id | int(11) | NO | PRI | NULL | auto_increment |
| candidate_id | int(11) | NO | MUL | NULL | |
| company_id | int(11) | NO | MUL | NULL | |
| start_date | date | NO | MUL | NULL | |
| end_date | date | NO | MUL | NULL | |
+--------------+---------+------+-----+---------+----------------+
.
mysql> describe candidates;
+----------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+----------+------+-----+---------+----------------+
| candidate_id | int(11) | NO | PRI | NULL | auto_increment |
| candidate_name | char(50) | NO | MUL | NULL | |
| home_city | char(50) | NO | MUL | NULL | |
+----------------+----------+------+-----+---------+----------------+
.
mysql> describe companies;
+-------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------------+------+-----+---------+----------------+
| company_id | int(11) | NO | PRI | NULL | auto_increment |
| company_name | char(50) | NO | MUL | NULL | |
| company_city | char(50) | NO | MUL | NULL | |
| company_post_code | char(50) | NO | | NULL | |
| latitude | decimal(11,8) | NO | | NULL | |
| longitude | decimal(11,8) | NO | | NULL | |
+-------------------+---------------+------+-----+---------+----------------+
.
Note that I should probably call this skill_usage, as it indicates when a skill was use don a job.
mysql> describe skills;
+----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| skill_id | int(11) | NO | MUL | NULL | |
| job_id | int(11) | NO | MUL | NULL | |
+----------+---------+------+-----+---------+-------+
.
mysql> describe skill_names;
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| skill_id | int(11) | NO | PRI | NULL | auto_increment |
| skill_name | char(32) | NO | MUL | NULL | |
+------------+----------+------+-----+---------+----------------+
So far, my MySQL query looks like this:
SELECT DISTINCT can.candidate_id,
can.candidate_name,
can.candidate_city,
j.job_id,
j.company_id,
DATE_FORMAT(j.start_date, "%b %Y") AS start_date,
DATE_FORMAT(j.end_date, "%b %Y") AS end_date,
s.skill_id
FROM candidates AS can
INNER JOIN jobs AS j ON j.candidate_id = can.candidate_id
INNER JOIN companies AS co ON j.company_id = co.company_id
INNER JOIN skills AS s ON s.job_id = j.job_id
INNER JOIN skill_names AS sn ON s.skill_id = s.skill_id
AND sn.skill_id = s.skill_id
ORDER by can.candidate_id, j.job_id
I am getting output like this, but am not satisfied with it
+--------------+----------------+---------------------+--------+------------+------------+------------+----------+
| candidate_id | candidate_name | candidate_city | job_id | company_id | start_date | end_date | skill_id |
+--------------+----------------+---------------------+--------+------------+------------+------------+----------+
| 1 | Pamela Brown | Cardiff | 1 | 3 | 2019-01-01 | 2019-08-31 | 1 |
| 1 | Pamela Brown | Cardiff | 1 | 3 | 2019-01-01 | 2019-08-31 | 2 |
| 1 | Pamela Brown | Cardiff | 1 | 3 | 2019-01-01 | 2019-08-31 | 1 |
| 1 | Pamela Brown | Cardiff | 2 | 2 | 2018-06-01 | 2019-01-31 | 3 |
| 1 | Pamela Brown | Cardiff | 3 | 1 | 2017-11-01 | 2018-06-30 | 4 |
| 1 | Pamela Brown | Cardiff | 3 | 1 | 2017-11-01 | 2018-06-30 | 5 |
| 1 | Pamela Brown | Cardiff | 3 | 1 | 2017-11-01 | 2018-06-30 | 6 |
| 1 | Pamela Brown | Cardiff | 4 | 3 | 2016-08-01 | 2017-11-30 | 1 |
| 2 | Christine Hill | Salisbury | 5 | 2 | 2018-02-01 | 2019-05-31 | 3 |
Now, I would like to restrict the search, by specifying "skill", like Python, C, C++, UML, etc and company names
The user will enter something like Python AND C++ into a skill search box (and/or Microsoft OR Google into a company name search box).
How do I feed that into my query? Please bear in mind that each skill ID has a job Id associated with it. Maybe I first need to convert the skill names from the search (in this case Python C++) into skill Ids? Even so, how do I include that in my query?
Te make a few things clearer:
both the skills & company search box can be empty, which I will interpret as "return everything"
search terms can include the keywords AND and OR, with grouping brackets (NOT is not required). I am happy enough to parse that in PHP & turn it into a MySQL query term (my difficulty is only with SQL, not PHP)
It looks like I made a start, with that INNER JOIN skills AS s ON s.job_id = j.job_id, which I think will handle a search for a single skill, given its ... name ? ... Id?
I suppose my question would be how would that query look if, for example, I wanted to restrict the results to anyone who had worked at Microsoft OR Google and has the skills Python AND C++?
If I get an example for that, I can extrapolate, but, at this point, I am unsure whether I want more INNER JOINs or WHERE clauses.
I think that I want to extend that second last line AND sn.skill_id = s.skill_id by paring the skills search string, in my example Python AND C++ and generating some SQL along the lines of AND (s.skill_id = X ), where X is the skill Id for Python, BUT I don't know how to handle Python AND C++, or something more complex, like Python AND (C OR C++) ...
Update
Just to be clear, the users are technical and expect to be able to enter complex searches. E.g for skills: (C AND kernel)OR (C++ AND realtime) OR (Doors AND (UML OR QT)).
Final update
The requirements just changed. The person that I am coding this for just told me that if a candidate matches the skill search on any job that he ever worked, then I ought to return ALL jobs for that candidate.
That sounds counter-intuitive to me, but he swears that that is what he wants. I am not sure it can even be done in a single query (I am considering multiple queries; a first t get the candidates with matching skills, then a second to get all of their jobs).
The first thing I'd say is that your original query probably needs an outer join on the skills table - as it stands, it only retrieves people whose job has a skill (which may not be all jobs). You say that "both the skills & company search box can be empty, which I will interpret as return everything" - this version of the query will not return everything.
Secondly, I'd rename your "skills" table to "job_skills", and your "skill_names" to "skills" - it's more consistent (your companies table is not called company_names).
The query you show has a duplication - AND sn.skill_id = s.skill_id duplicates the terms of your join. Is that intentional?
To answer your question: I would present the skills to your users in some kind of pre-defined list in your PHP, associated with a skill_id. You could have all skills listed with check boxes, or allow the user to start typing and use AJAX to search for skills matching the text. This solves a UI problem (what if the user tries to search for a skill that doesn't exist?), and makes the SQL slightly easier.
Your query then becomes:
SELECT DISTINCT can.candidate_id,
can.candidate_name,
can.candidate_city,
j.job_id,
j.company_id,
DATE_FORMAT(j.start_date, "%b %Y") AS start_date,
DATE_FORMAT(j.end_date, "%b %Y") AS end_date,
s.skill_id
FROM candidates AS can
INNER JOIN jobs AS j ON j.candidate_id = can.candidate_id
INNER JOIN companies AS co ON j.company_id = co.company_id
INNER JOIN skills AS s ON s.job_id = j.job_id
INNER JOIN skill_names AS sn ON s.skill_id = s.skill_id
AND skill_id in (?, ?, ?)
OR skill_id in (?)
ORDER by can.candidate_id, j.job_id
You need to substitute the question marks for the input your users have entered.
EDIT
The problem with allowing users to enter the skills as free text is that you then have to deal with case conversion, white space and typos. For instance, is "python " the same as "Python"? Your user probably intends it to be, but you can't do a simple comparison with skill_name. If you want to allow free text, one solution might be to add a "normalized" skill_name column in which you store the name in a consistent format (e.g. "all upper case, stripped of whitespace"), and you normalize your input values in the same way, then compare to that normalized column. In that case, the "in clause" becomes something like:
AND skill_id in (select skill_id from skill_name where skill_name_normalized in (?, ?, ?))
The boolean logic you mention - (C OR C++) AND (Agile) - gets pretty tricky. You end up writing a "visual query builder". You may want to Google this term - there are some good examples.
You've narrowed down your requirements somewhat (I may misunderstand). I believe your requirements are
I want to be able to specify zero or more filters.
A filter consists of one or more ANDed skill groups.
A skill group consists of one or more skills.
Filters are ORed together to create a query.
To make this concrete, let's use your example - (A and (B OR C)) OR (D AND (E OR F)). There are two filters: (A and (B OR C)) and (D AND (E OR F)). The first filter has two skill groups: A and (B OR C).
It's hard to explain the suggestion in text, but you could create a UI that allows users to specify individual "filters". Each "filter" would allow the user to specify one or more "in clauses", joined with an "and". You could then convert this into SQL - again, using your example, the SQL query becomes
SELECT DISTINCT can.candidate_id,
can.candidate_name,
can.candidate_city,
j.job_id,
j.company_id,
DATE_FORMAT(j.start_date, "%b %Y") AS start_date,
DATE_FORMAT(j.end_date, "%b %Y") AS end_date,
s.skill_id
FROM candidates AS can
INNER JOIN jobs AS j ON j.candidate_id = can.candidate_id
INNER JOIN companies AS co ON j.company_id = co.company_id
INNER JOIN skills AS s ON s.job_id = j.job_id
INNER JOIN skill_names AS sn ON s.skill_id = s.skill_id
AND
(skill_id in (A) and skil_id in (B, C))
OR
(skill_id in (D) and skil_id in (E, F))
ORDER by can.candidate_id, j.job_id
Building a bit off previous comments and answers... if handling input like
(A and (B OR C)) OR (D AND (E OR F))
is the blocker you could try moving some of the conditional logic out of the joins and filter instead.
WHERE (
((sn.skill_id LIKE 'A') AND ((sn.skill_id LIKE ('B')) OR (sn.skill_id LIKE('C'))))
AND ((co.company_id IN (1,2,3)) AND ((can.city = 'Springfield') OR (j.city LIKE('Mordor'))))
)
You can build your query string based off used input, search out Id's for selected values and put them into the string and conditionally build as many filters as you like. Think about setting up add_and_filter and add_or_filter functions to construct the <db>.<field> <CONDITION> <VALUE> statements.
$qs = "";
$qs .= "select val from table";
...
$qs .= " WHERE ";
if($userinput){ $qs += add_and_filter($userinput); }
alternately, look at a map/reduce pattern rather than trying to do it all in SQL?

How To: Insert into column where the value is on another table

Summarize the Problem:
I want to write a booking code. I had a little problem, that I wanted to insert a value into the booked table that is in another table called house_info.
The detail of booked & house_info database is below:
Booked Table
ID_Booking | House_Name | House_ID | House_No | House_Qty | House_Price |
1 | Rose House | 1 | RH01 | 1 | |
2 | Rose House | 1 | RH02 | 1 | |
House Info Table
House_ID | HouseState_Name | House_Qty | House_Price |
1 | Garden City | 8 | 40000|
2 | Electronic City | 10 | 1000000|
I want to insert the House_Price value on the house_info table into the House_Price column on booked table every time users input on the Booking Form.
Background you've already tried:
I already tried this using a trigger on booked table like below:
Trigger on Booked Table (Before Insert)
IF NEW.House_ID= '1' THEN SET
NEW.House_Price = 40000;
ELSEIF NEW.House_ID= '2' THEN SET
NEW.House_Price = 1000000;
But I realize this is not dynamic because when the company want to change the price of each HouseState_Name he needs to change it from the trigger. So I think what I needed is a query from PHP that can calls the value of each HouseState_Name and hold it on an array and place it or insert it when the Book Query passed (I hope my logic is true, I'm sorry if it's false).
I already tried to search too for the query's to use. But I didn't know how am I going to use the query.
Some Codes:
Booking.php
require 'Connection.php';
//Check Connection
if ($conn->connect_error){
die("Connection Failed: ". $conn->connect_error);
}
//Check for Submit
if (filter_has_var(INPUT_POST, 'Submit')) {
//Get Form Data
$CustomerEmail= htmlspecialchars($_POST["Email"], ENT_QUOTES);
$House_Name= htmlspecialchars($_POST["HouseName"], ENT_QUOTES);
$House_ID = htmlspecialchars($_POST["HouseID "], ENT_QUOTES);
$House_No = htmlspecialchars($_POST["HouseNo "], ENT_QUOTES);
//Validate the data fields
if (!empty($CustomerEmail) && !empty($House_Name)) {
//Passed
if (filter_var($CustomerEmail, FILTER_VALIDATE_EMAIL) === false) {
//Failed
$msg = 'Please use a valid email';
header("location: ../GardenCity.php?error=PleaseUseValidEmail");
} else {
//Passed
echo "Creating a Booking.<br>";
//Inserting the Booking Data into Database
$sql = "INSERT INTO `booked`(`ID_Booking`, `CustomerEmail`, `House_Name`, `House_ID`, `House_No`)
VALUES (NULL, '$CustomerEmail', '$House_Name', '$House_ID ', '$House_No', '', '')";
if ($conn->query($sql) === TRUE) {
header("location: ../GardenCity.php");
} else {
echo "Error: " . $sql . "<br><br>" . $conn->error;
}
}
} else {
header("location: ../GardenCity.php?error=EmptyFields");
}
}
$conn -> close();
Expected Results:
Before Update the price
Database Looks
ID_Booking | House_Name | House_ID | House_No | House_Qty | House_Price |
1 | Rose House | 1 | RH01 | 1 | |
2 | Rose House | 1 | RH02 | 1 | |
3 | Rose House | 1 | RH03 | 1 | 40000|
House_ID | HouseState_Name | House_Qty | House_Price |
1 | Garden City | 7 | 40000|
2 | Electronic City | 10 | 1000000|
After Update the price
Database Looks
ID_Booking | House_Name | House_ID | House_No | House_Qty | House_Price |
1 | Rose House | 1 | RH01 | 1 | |
2 | Rose House | 1 | RH02 | 1 | |
3 | Rose House | 1 | RH03 | 1 | 40000|
4 | Rose House | 1 | RH04 | 1 | 200000|
House_ID | HouseState_Name | House_Qty | House_Price |
1 | Garden City | 6 | 200000|
2 | Electronic City | 10 | 1000000|
I hope this is well explained. Please let me know if there's any confusing statements or questions. I will say many thanks to you all if this is answered because I'm so stuck at this and my brain won't work.
I think this could work, basically using a subquery just to fetch the price, that should achieve the same result as your insert trigger, but without using fixed prices.
INSERT INTO `booked` (
`ID_Booking`,
`CustomerEmail`,
`House_Name`,
`House_ID`,
`House_No`,
`House_Qty`,
`House_Price`
) VALUES (
NULL,
'$CustomerEmail',
'$House_Name',
'$House_ID',
'$House_No',
'1',
(SELECT House_Price FROM house_info WHERE House_ID = '$House_ID')
)
Edit: I set House_Qty at 1, change it according to your needs :)
Maybe you can use the same subquery in your trigger directly instead (haven't tested it) :
SET NEW.House_Price =
(SELECT House_Price FROM house_info WHERE House_ID = NEW.House_id);
Assuming your House_ID are unique :)
I would expect to see a schema more or less like this:
houses(house_id*,name)
house_prices(house_id*,price_start_date*,price)
bookings(booking_id*,customer_id,total)
booking_detail(booking_id*,house_id*,start_date,end_date)
* = (component of) PRIMARY KEY
After some reflection, it should be apparent that your present concerns evaporate with this design.
Insert Into booked_table (ID_Booking, House_Name, House_Id, House_No, House_Qty, House_Price)
Select 1, House_Name, House_ID, 'RHXX', House_Qty, (SELECT House_Price FROM house_info WHERE House_ID = MM1.House_ID) From booked_table MM1
Where
NOT EXISTS(
SELECT *
FROM booked_table MM2
WHERE MM2.ID_Booking > MM1.ID_Booking
);
Fiddle: https://www.db-fiddle.com/f/7Bt3ZTQqbjs1jKzJe34qSF/0
I dont included the increment of the ID_Booking and House_No.
If you want to increase the House_Price, just do that with another query.
You can construct such an UPDATE statement with INNER JOINs one of which's in the subquery as a self-JOIN for booked table, put after your existing INSERT statement :
update house_info h join (
select b1.House_Price, b2.House_ID
from booked b1
join ( select House_ID,max(ID_Booking) as ID_Booking
from booked
group by House_ID
) b2
on b1.House_ID = b2.House_ID and b1.ID_Booking = b2.ID_Booking
) bb on bb.House_ID = h.House_ID
set h.House_Price = bb.House_Price;
but I should admit that your tables' design is not good, because of repeating columns they hold the same information in each.
Demo

MySQL query to fetch rows from different table with multiple rows into respective column

We have two tables as below:
Table-1 Name: apprecord
---------------------------------------
appid | desc | status
ALT01 | this is first | Open
ALT02 | this is second | Open
ALT03 | this is third | Closed
---------------------------------------
Table-2 Name: question
-----------------------------------------------
appid | questionseq | ques | ans
ALT01 | 1 | how are you | good
ALT01 | 2 | are you fine | yes
ALT02 | 1 | how was your day | great
ALT02 | 2 | are you coming today | yes
ALT03 | 1 | where are you | at home
ALT03 | 2 | are you fine | yes
--------------------------------------------------
How can I write a MySQL query so that I can get the result as below:
----------------------------------------------------------------------------------------
appid | desc | status| QUES1 | ANS1 | QUES2 | ANS2
ALT01 | this is first | Open | how are you | good | are you fine | yes
ALT02 | this is second| Open | how was your day| great | are you coming today | no
ALT03 | this is third | Closed| where are you | at home| are you fine | yes
---------------------------------------------------------------------------------------
Here QUES1, ANS1, QUES2, ANS2 are hardcoded/fixed column headers.
Try this:
Sample data:
create table apprecord(appid varchar(10),desc varchar(100),status varchar(10));
insert into apprecord values
('ALT01','this is first','Open'),
('ALT02','this is second','Open'),
('ALT03','this is third','Closed');
create table question(appid varchar(10),questionseq int,ques varchar(100),ans varchar(10));
insert into question values
('ALT01',1,'how are you','good'),
('ALT01',2,'are you fine','yes'),
('ALT02',1,'how was your day','great'),
('ALT02',2,'are you coming today','yes'),
('ALT03',1,'where are you','at home'),
('ALT03',2,'are you fine','yes');
T-SQL:
select ar.appid,
`desc`,
`status`,
q1.ques ques1,
q1.ans ans1,
q2.ques ques2,
q2.ans ans2
from apprecord ar
left join (select appid, ques, ans from question where questionseq = 1) q1
on ar.appid = q1.appid
left join (select appid, ques, ans from question where questionseq = 2) q2
on ar.appid = q2.appid
This is standard pivoting, although it can be dane as above, using two joins :)

SQL query returning empty set

I have this table
| BookID | BookTitle | NumberOfPages | NoOfCopies |
+--------+--------------------------------+---------------+------------+
| 1 | The Help | 444 | 4 |
| 2 | The Catcher in the Rye | 277 | 10 |
| 3 | Crime and Punishment | 545 | 2 |
| 4 | The Brothers Karamazov | 795 | 1 |
| 5 | A Crown of Wishes | 369 | 12 |
| 6 | The Fireman | 752 | 3 |
| 7 | Fahrenheit 451 | 174 | 9 |
| 8 | The Hobbit | 366 | 1 |
| 9 | Lord of Emperors | 560 | 4 |
| 10 | Holy Bible: King James Version | 1590 | 11 |
----------------------------------------------------------------------------
When I insert a book title and expect it to return the book id, it always returns an empty set
so far, I have tried these queries.->book_info is the name of the table:
select BookID from book_info where ucase(BookTitle) = ' THE HELP% ';
select BookID from book_info where BookTitle = ' The Help ';
select BookID from book_info where lcase(trim(BookTitle) = 'the help';
but none of them worked.
Note I don't rely on sql in my job.
you need to use like if you want to use "%"
when you use "=" you need to sure it is same. even space also count
select BookID from book_info where BookTitle LIKE 'THE HELP%';
The issue here is with the operator you are using and the value you are function you are expecting from it, = operator checks for the exact match that's why your queries are returning no records:
select BookID from book_info where ucase(BookTitle) = ' THE HELP% ';
select BookID from book_info where BookTitle = ' The Help ';
select BookID from book_info where lcase(trim(BookTitle) = 'the help';
And one more thing that is:
MySQL queries are not case-sensitive by default.
So you don't need to add the string methods here to change the values case.
We usually use the % with LIKE only like this:
select BookID from book_info where ucase(BookTitle) LIKE '%THE HELP%';
In this query LIKE %THE HELP% will match all the string having THE HELP in them;