sql ms access select by date and genre - ms-access

I have two tables:
fID Enamn Fnamn bdate
1 Ronge Paus 49-05-14
2 Nesser Håk 50-07-26
3 Bods Thomas 51-05-02
And
ISBN cathegory
123 Prosa
456 Poesi
789 Thriller
I am trying to select by date and cathegory. The writer shoult be born before year "1950" and the cathegory should be "Poesi"
The result should be:
ISBN cathegory fID Enamn Fnamn bdate
456 poesi 1 Ronge Paus 49-05-14
I have tried the followin:
SELECT *
FROM bok, författare
WHERE bdate BETWEEN #01/01/40# AND #01/01/50# AND kategori = 'poesi'
But it didn't work :(

You need a method to match a record from the first table to it's category in the second table. I assumed ISBN is the primary key in the second table, so used it as a foreign key in the first table.
I am unclear about the table names, so I substituted my own names. Notice I also assumed bdate is Date/Time data type. Here's what my versions of the tables look like:
tblA:
fID Enamn Fnamn bdate fkey_ISBN
1 Ronge Paus 49-05-14 456
2 Nesser Håk 50-07-26 123
3 Bods Thomas 51-05-02 789
tblB:
ISBN cathegory
123 Prosa
456 Poesi
789 Thriller
Then, to get writers born before year 1950 for cathegory "Poesi", use this query:
SELECT
a.fkey_ISBN,
b.cathegory,
a.fID,
a.Enamn,
a.Fnamn,
a.bdate
FROM
tblA AS a
INNER JOIN tblB AS b
ON a.fkey_ISBN = b.ISBN
WHERE
a.bdate < #1950/01/01#
AND b.kategori = 'poesi';
Edit: If ISBN is in fact the primary key of tblB, you may get better performance by using ISBN rather than kategori in your WHERE clause:
WHERE
a.bdate < #1950/01/01#
AND b.ISBN = 456
or if IBSN is text rather than numeric data type:
WHERE
a.bdate < #1950/01/01#
AND b.ISBN = '456'

Related

MySQL query to gather incorrectly stored data

I have recently taken over a email campaign project and need to generate a report for the customer. However the data has been stored very strangely.
Basically the client wants a report of the subscribers first name and last name that have subscribed to a emailing list.
Example table data.
------------------------------------------------------------
id | owner_id | list_id | field_id | email_address | value
------------------------------------------------------------
1 10 1 137 me#example.com John
2 10 1 138 me#example.com Doe
So as you can see, John Doe has subscribed to mailing list 1, and field_id 137 is his first name and field_id 138 is his last name.
The client is looking for a export with the users first name and last name all is one field.
I tred the following sql query
SELECT value
FROM Table_A AS child
INNER JOIN Table_A AS parent
ON parent.email_address = child.email_address
WHERE child.owner_id = '10'
But unfortunately the query gives me the results in many rows but not appending the first name and last name into one field,
If anyone can provide some assistance that would be awesome.
Thanks.
SELECT
concat( parent.value,' ',child.value)name
FROM mytable AS child
left JOIN mytable AS parent
ON parent.email_address = child.email_address
WHERE child.owner_id = '10'
and parent.field_id=137 and child.field_id=138
Check at-http://sqlfiddle.com/#!9/199b4b/45
I think you have to use a variable to put in there everything you have to and then select the variable with the desired name of yours.
For example:
DECLARE #yourvariable VARCHAR(MAX)
SELECT #yourvariable = COALESCE(#yourvariable + " ") + value
FROM table_A
WHERE owner_id = 10
SELECT #yourvariable as FullName
Try that, it might help.
You can try this code(column name equals value in your original DB):
select a.name
from
table_a a inner join table_a b
on a.email_address = b.email_address and a.field_id <> b.field_id
where a.owner_id=10
order by a.field_id
Here is the example link:
http://sqlfiddle.com/#!9/5fbdf6/25/0
As per assumptions, first name has the field id 137 and last name has the field id 138.
You can try the following query to get the desired result.
SELECT CONCAT(SUBSTRING_INDEX(GROUP_CONCAT(`value`),",",1)," ",SUBSTRING_INDEX(GROUP_CONCAT(`value`),",",-1)) AS client_name
FROM Table_A
WHERE owner_id = 10
AND field_id IN (137, 138)
GROUP BY email_address;

mysql count last_column_data not working

I have a table name: serial
ID Name Date
---- -------- -----------
1 George 2013-07-24
2 John 2013-07-24
3 Thomas 2013-07-25
4 James 2013-07-31
5 Andrew 2013-07-20
6 Martin 2013-07-24
7 William 2013-07-21
8 Zachary 2013-07-25
9 Millard 2013-07-31
10 Chester 2013-07-24
Now I need count of the last value of column Date dynamically, here the last value of column Date is 2013-07-24, so the count is 4. But if some data insert into ID#11 with the Date value 2013-07-31,then the count will be 3.
I have made a function to do this:
function countdate(){
$SQL = "SELECT count( `ID` ) as countdate FROM serial WHERE `Date` = 'LAST(Date)'";
$result = mysql_query($SQL);
$cd= mysql_fetch_array($result);
return $cd['countdate'];
}
But it is not working. But if I put directly '2013-07-24' instead of 'LAST(Date)' into the function, it gives the result. I think 'LAST(Date)' is not working here dynamically.
What is the mistake here or any other way......By the way, I am not very expert coder, and it's my first question, so...
Here MAX(value) might not work as different dates are insert into here. MAX(value) may work here if we consider the column 'ID'. But the values of the column 'Date' not incremental here.
Try with a sub query:
SELECT COUNT(*) countdate FROM serial WHERE `Date` = (SELECT `Date` FROM serial order by ID desc limit 1)

Update access column from existing values

I have a MS access table with the following columns and sample records.
How do I update the adDate value with the least LastSaleDate for each ProductID.
orderID productID lastsaleDate adDate
1 1 10/20/2012
2 1 5/10/2007
3 1 4/1/2004
4 1 20/11/2011
5 2 10/10/2010
6 2 12/10/1972
For example the adDate for ProductID 1 will be 4/1/2004
and for ProductID 2 will be 12/10/1972
You can use DMin:
UPDATE sales
SET sales.adDate = DMin("lastsaleDate","sales","productID=" & productid)
Unless you have a compelling reason to actually store adDate values in your table, consider simply computing adDate with a query any time you need it. That way you don't risk ever displaying adDate values which have not been updated to reflect the latest changes to the underlying data.
SELECT
y.orderID,
y.productID,
y.lastsaleDate,
sub.adDate
FROM
YourTable AS y
INNER JOIN
(
SELECT productID, Min(lastsaleDate) AS adDate
FROM YourTable
GROUP BY productID
) AS sub
ON y.productID = sub.productID;

Using 'AND' in SQL WHERE clause for the same filed

Here is the scenario. I have 1 table that has all the contact details. Another table that has all the list of Categories. And a 3rd table which is an associate table, that has the ID of the first table and the ID of the second table.
This is how my associate table looks like
contactdid -2 | categoryid -1
contactdid -2 | categoryid -2
contactdid -2 | categoryid -3
contactdid -3 | categoryid -1
contactdid -3 | categoryid -3
This is my SQL code below(Generated using SQLyog and i included the where clause).
SELECT
press_contacts.email
FROM
contacts_category
INNER JOIN press_category
ON (contacts_category.categoryid = press_category.id)
INNER JOIN press_contacts
ON (contacts_category.contactdid = press_contacts.id)
WHERE contacts_category.categoryid = 1 AND contacts_category.categoryid = 2 ;
I get the output when I do not have AND contacts_category.categoryid = 2inserted in the code.
Any idea how to solve this.I clearly have data.
Thanks in advance for the help.
contacts_category.categoryid can not be 1 and 2 at the same time, perhabs you mean OR instead of AND?
Use OR or IN() instead of AND.
A field can't have two values at the same time
If you only want to see those email addresses with contacts in both categories, try:
SELECT press_contacts.email
FROM contacts_category
INNER JOIN press_contacts
ON (contacts_category.contactdid = press_contacts.id)
WHERE contacts_category.categoryid in (1, 2)
GROUP BY press_contacts.email
HAVING COUNT(DISTINCT contacts_category.categoryid)=2

MySQL - What's wrong with the query?

I am trying to query a database to find the following.
If a customer searches for a hotel in a city between dates A and B, find and return the hotels in which rooms are free between the two dates.
There will be more than one room in each room type (i.e. 5 Rooms in type A, 10 rooms in Type B, etc.) and we have to query the database to find only those hotels in which there is at least one room free in at least one type.
This is my table structure:
**Structure for table 'reservations'**
reservation_id
hotel_id
room_id
customer_id
payment_id
no_of_rooms
check_in_date
check_out_date
reservation_date
**Structure for table 'hotels'**
hotel_id
hotel_name
hotel_description
hotel_address
hotel_location
hotel_country
hotel_city
hotel_type
hotel_stars
hotel_image
hotel_deleted
**Structure for table 'rooms'**
room_id
hotel_id
room_name
max_persons
total_rooms
room_price
room_image
agent_commision
room_facilities
service_tax
vat
city_tax
room_description
room_deleted
And this is my query:
$city_search = '15';
$check_in_date = '29-03-2010';
$check_out_date = '31-03-2010';
$dateFormat_check_in = "DATE_FORMAT('$reservations.check_in_date','%d-%m-%Y')";
$dateFormat_check_out = "DATE_FORMAT('$reservations.check_out_date','%d-%m-%Y')";
$dateCheck = "$dateFormat_check_in >= '$check_in_date' AND $dateFormat_check_out <= '$check_out_date'";
$query = "SELECT $rooms.room_id,
$rooms.room_name,
$rooms.max_persons,
$rooms.room_price,
$hotels.hotel_id,
$hotels.hotel_name,
$hotels.hotel_stars,
$hotels.hotel_type
FROM $hotels,$rooms,$reservations
WHERE $hotels.hotel_city = '$city_search'
AND $hotels.hotel_id = $rooms.hotel_id
AND $hotels.hotel_deleted = '0'
AND $rooms.room_deleted = '0'
AND $rooms.total_rooms - (SELECT SUM($reservations.no_of_rooms) as tot
FROM $reservations
WHERE $dateCheck
GROUP BY $reservations.room_id) > '0'";
The number of rooms already reserved in each room type in each hotel will be stored in the reservations table.
The thing is the query doesn't return any result at all. Even though it should if I calculate it myself manually.
I tried running the sub-query alone and I don't get any result. And I have lost quite some amount of hair trying to de-bug this query from yesterday. What's wrong with this? Or is there a better way to do what I mentioned above?
Edit: Code edited to remove a bug. Thanks to Mark Byers.
Sample Data in reservation table
1 1 1 2 1 3 2010-03-29 2010-03-31 2010-03-17
2 1 2 3 3 8 2010-03-29 2010-03-31 2010-03-18
5 1 1 5 5 4 2010-03-29 2010-03-31 2010-03-12
The sub-query should return
Room ID : 1 Rooms Booked : 7
Room ID : 2 Rooms Booked : 8
But it does not return any value at all.... If i remove the dateCheck condition it returns
Room ID : 2 Rooms Booked : 8
Your problem is here:
$rooms.total_rooms - (SELECT SUM($reservations.no_of_rooms) as tot,
$rooms.room_id as id
FROM $reservations,$rooms
WHERE $dateCheck
GROUP BY $reservations.room_id) > '0'"
You are doing a subtraction total_rooms - (tot, id) where the first operand is a scalar value and the second is a table with two columns. Remove one of the columns in the result set and make sure you only return only one row.
You also should use the JOIN keyword to make joins instead of separating the tables with commas. That way you won't forget to add the join condition.
You probably want something along these lines:
SELECT column1, column2, etc...
FROM $hotels
JOIN $rooms
ON $hotels.hotel_id = $rooms.hotel_id
JOIN (
SELECT SUM($reservations.no_of_rooms) as tot,
$rooms.room_id as id
FROM $reservations
JOIN $rooms
ON ??? /* Aren't you missing something here? */
WHERE $dateCheck
GROUP BY $reservations.room_id
) AS T1
ON T1.id = room_id
WHERE $hotels.hotel_city = '$city_search'
AND $hotels.hotel_deleted = '0'
AND $rooms.room_deleted = '0'
AND $rooms.total_rooms - T1.tot > '0'