Not getting desired result using join in mysql - mysql

I tried left,right,inner join here is my tables
SHOP_OFFER_STATUS
+-----------------------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+--------------+------+-----+---------------------+----------------+
| MOBILE_NUM | varchar(100) | YES | | NULL | |
| SHOP_ID | varchar(100) | YES | | NULL | |
| OFFER_ID | int(255) | YES | | NULL | |
| OFFER_STATUS | varchar(100) | YES | | NULL | |
| OFFER_GENERATED_ID | int(255) | NO | PRI | NULL | auto_increment |
| OFFER_GENERATED_DATE | timestamp | NO | | CURRENT_TIMESTAMP | |
| OFFER_EXPIRY_DATE | timestamp | NO | | 0000-00-00 00:00:00 | |
| OFFER_CODE | varchar(10) | YES | | NULL | |
| AMOUNT | decimal(9,2) | YES | | NULL | |
| BILL_AMOUNT | decimal(9,2) | YES | | NULL | |
+-----------------------+--------------+------+-----+---------------------+----------------+
TRACK_TRANSACTIONS
+------------------+---------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------------+------+-----+-------------------+----------------+
| TRANSACTION_ID | int(255) | NO | PRI | NULL | auto_increment |
| TRANCTION_TYPE | varchar(100) | YES | MUL | NULL | |
| TRANSACTION_DATE | timestamp | NO | | CURRENT_TIMESTAMP | |
| AMOUNT | decimal(10,2) | YES | | NULL | |
| MOBILE_NUM | varchar(15) | YES | | NULL | |
| SHOP_ID | varchar(200) | YES | | NULL | |
+------------------+---------------+------+-----+-------------------+----------------+
i know its my design problem and i have thousands of records(can't rollback or redesign),here how it works when ever person redeems the offer in transaction table shop_id and mobile_num will be added I am trying to get BILL_AMOUNT,TRANSACTION_DATE from this tables...but its giving wrong result...i want to know when(TRANSACTION_DATE ) and what amount he redeemed!
TRANSACTION table have many other transactions like usercreated,commented etc(TRANCTION_TYPE) and offer redemption are around TRANCTION_TYPE='MERCHANT CASHBACK' 100 records if i join this tables more then 50 thousands records comes in :( here is the query!
SELECT COUNT(*)
FROM TRACK_TRANSACTIONS T RIGHT JOIN
SHOP_OFFER_STATUS S
ON T.SHOP_ID=S.SHOP_ID
WHERE T.TRANCTION_TYPE='MERCHANT CASHBACK' AND S.OFFER_STATUS='REDEEMED';
the desired output:100 records where offer redemption happend!

Related

MySQL stored procedure architecture

I am working on a piece of code that runs a query against MySQL. The syntax is below:
SELECT `order`.`id` AS `id`,
IFNULL(product.main_name, product.name) AS `variant`,
`product`.`id` AS `product_id`,
`product`.`cost` AS `cost`,
ROUND(SUM(order.price), 2) AS `price`,
SUM(order.quantity) AS `quantity`,
`product`.`sku` AS `sku`,
ROUND(order.price/order.quantity, 2) AS `avg_price`,
`product`.`quantity` AS `qty_at_hand`,
`order`.`fulfillment_channel` AS `fulfillment_channel`,
0 as `returns`
FROM `order`
LEFT JOIN `product` ON product.sku = order.sku
WHERE (`order`.`account_id`=1)
AND (`order`.`item_status`<>'Cancelled')
AND (`order`.`purchase_date` >= $start_date)
AND (`order`.`purchase_date` <= $end_date)
GROUP BY `order`.`sku`
My order table:
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | MUL | NULL | |
| account_id | int(11) | NO | MUL | NULL | |
| merchant_order_id | varchar(255) | NO | | NULL | |
| purchase_date | datetime | NO | | NULL | |
| updated_date | datetime | NO | | NULL | |
| order_status | varchar(255) | NO | | NULL | |
| product_name | varchar(255) | NO | | NULL | |
| sku | varchar(255) | NO | MUL | NULL | |
| item_status | varchar(255) | NO | | NULL | |
| quantity | int(11) | NO | | NULL | |
| currency | varchar(10) | NO | | NULL | |
| price | decimal(9,2) | YES | | 0.00 | |
| created_at | datetime | NO | | CURRENT_TIMESTAMP | |
| fulfillment_channel | varchar(255) | YES | | NULL | |
My product table:
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | MUL | NULL | |
| account_id | int(11) | NO | MUL | NULL | |
| name | varchar(255) | NO | | NULL | |
| main_name | varchar(255) | YES | | NULL | |
| description | text | YES | | NULL | |
| listing_id | varchar(255) | YES | | NULL | |
| sku | varchar(255) | NO | MUL | NULL | |
| open_date | datetime | YES | | NULL | |
| price | decimal(9,2) | NO | | 0.00 | |
| quantity | int(11) | YES | | NULL | |
| supplier_id | int(11) | YES | | NULL | |
| active | tinyint(1) | NO | | 1 | |
| supplier_sku | varchar(255) | YES | | NULL | |
| upc | varchar(255) | YES | | NULL | |
| tag | varchar(255) | YES | | NULL | |
| cost | decimal(9,2) | NO | | 0.00 | |
| ean | int(11) | YES | | NULL | |
| min_order_qty | int(11) | YES | | NULL | |
The query is working fine. However, I would like to replace the QUERY with a stored procedure - a function would take three (3) arguments: start_date, end_date and a boolean flag called full.
I would like the full to be interpreted in a the following way:
- if full is set to false, return the same results query returns now;
- if full is set to true, return a row for each entry in the products table with quantity, price and average price returned as 0, if where fails merged with the query results - a row for each product, whether where were orders in the set period or not.
I was thinking about making a temporary table, then running an update on it and dumping the table after the data has been returned?
What would be the correct way to approach this?
Thank you
Add a UNION to this query and have it do an LEFT OUTER JOIN from Products to Orders table and in the WHERE clause check for full = true and only look for rows with Order.id is NULL. Union would only bring rows when full = true.
Prepare data in SELECT as you specified.

How to add a date selection in sql

I want to be able to select classes that are starting on or after the next two hours up until the end of tomorrow's date but I am not sure of how to do this.
My current sql is below, I have only been able to select classes that are after today's date and after the current time. I want to be able to only return classes that start two hours after now up until the end of tomorrows date.
I am able to pass the current date and current time into my node.js function that will construct the sql statement. Also, I have access to moment.js library if I need to use this I could.
Any help would be appreciated.
SELECT DISTINCT b.name
, a.time
FROM class a
Inner join (SELECT class_id, count(clientid)
FROM bookings
GROUP BY class_id
HAVING count(clientid) < 10) as openClasses on
a.class_id = openClasses.class_id
JOIN class_detail b
ON a.class_id = b.id
JOIN branch c
ON a.branch_id = c.id
WHERE c.level <= ( SELECT d.level
FROM client d
WHERE d.facebook_id = 'xxxxxx'
)
AND a.date = '2016-08-17'
AND a.time >= '13.00.00';
My tables are as follows:
BOOKINGS
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id | bigint(20) | NO | PRI | NULL | |
| CLIENT_ID | int(11) | NO | | NULL | |
| CLASS_ID | int(11) | NO | | NULL | |
| STATUS | varchar(10) | NO | | NULL | |
+-----------+-------------+------+-----+---------+-------+
mysql> show fields from BRANCH;
+---------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+-------------+------+-----+---------+----------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| NAME | char(50) | NO | | NULL | |
| CONTACT_NO | char(50) | YES | | NULL | |
| MAP_IMG_PATH | char(200) | YES | | NULL | |
| ADDRESS | char(200) | YES | | NULL | |
| LEVEL | int(2) | NO | | NULL | |
| LOCATION | int(10) | YES | | NULL | |
| SECTOR_NAME | varchar(45) | YES | | NULL | |
| SECTOR_MAP_IMG_PATH | char(200) | YES | | NULL | |
+---------------------+-------------+------+-----+---------+----------------+
mysql> show fields from CLIENT;
+--------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| id | int(10) | NO | PRI | NULL | |
| NAME | char(50) | NO | | NULL | |
| DOB | int(8) | NO | | NULL | |
| LOCAL_BRANCH | int(10) | YES | | NULL | |
| FACEBOOK_ID | char(50) | NO | | NULL | |
| START_DATE | int(8) | NO | | NULL | |
| EMAIL | char(50) | YES | | NULL | |
| PIN | int(4) | YES | | NULL | |
| END_DATE | int(8) | NO | | NULL | |
| LEVEL | int(2) | YES | | NULL | |
| TEL | varchar(20) | YES | | NULL | |
+--------------+-------------+------+-----+---------+-------+
mysql> show fields from CLASS_DETAIL;
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id | int(10) | NO | PRI | NULL | |
| NAME | char(50) | NO | | NULL | |
| DESCRIPTION | char(200) | NO | | NULL | |
| CATEGORY | varchar(4) | YES | | NULL | |
| ACHIEVE_TYPE | char(200) | YES | | NULL | |
| IMG_M | varchar(200) | YES | | NULL | |
| IMG_F | varchar(200) | YES | | NULL | |
+--------------+--------------+------+-----+---------+-------+
mysql> show fields from CLASS;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| CLASS_ID | int(10) | YES | | NULL | |
| BRANCH_ID | int(10) | NO | | NULL | |
| DURATION | int(3) | YES | | NULL | |
| DATE | date | NO | | NULL | |
| TIME | time | NO | | NULL | |
| STATUS | char(1) | NO | | NULL | |
+-----------+---------+------+-----+---------+----------------+
7 rows in set (0.11 sec)

MySQL Unknown column in where clause?

I have two databases.
One is called INFO with three tables (Stories, Comments, Replies)
Stories has the following fields
+--------------+----------------+------+-----+---------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+----------------+------+-----+---------------------+-----------------------------+
| storyID | int(11) | NO | PRI | NULL | |
| originalURL | varchar(500) | YES | | NULL | |
| originalDate | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| numDiggs | int(11) | YES | | NULL | |
| numComments | int(11) | YES | | NULL | |
| diggURL | varchar(500) | YES | | NULL | |
| rating | varchar(50) | YES | | NULL | |
| title | varchar(200) | YES | | NULL | |
| summary | varchar(10000) | YES | | NULL | |
| uploaderID | varchar(50) | YES | | NULL | |
| imageURL | varchar(500) | YES | | NULL | |
| category1 | varchar(50) | YES | | NULL | |
| category2 | varchar(50) | YES | | NULL | |
| uploadDate | timestamp | NO | | 0000-00-00 00:00:00 | |
| num | int(11) | YES | | NULL | |
+--------------+----------------+------+-----+---------------------+-----------------------------+
Another database is called Data with one table (User). Fields shown below:
+-------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-------------+------+-----+---------+-------+
| userID | varchar(50) | NO | PRI | NULL | |
| numStories | int(11) | YES | | NULL | |
| numComments | int(11) | YES | | NULL | |
| numReplies | int(11) | YES | | NULL | |
| numStoryDiggs | int(11) | YES | | NULL | |
| numCommentReplies | int(11) | YES | | NULL | |
| numReplyDiggs | int(11) | YES | | NULL | |
| numStoryComments | int(11) | YES | | NULL | |
| numStoryReplies | int(11) | YES | | NULL | |
+-------------------+-------------+------+-----+---------+-------+
User.userID is full of thousands of unique names. All other fields are currently NULL. The names in User.userID correspond to the names in Stories.uploaderID.
I need to, for each userID in User, count the number of stories uploaded from (i.e. num) Stories for the corresponding name and insert this value into User.numStories.
The query which I have come up with (which produces an error) is:
INSERT INTO DATA.User(numStories)
SELECT count(num)
FROM INFO.Stories
WHERE INFO.Stories.uploaderID=DATA.User.userID;
The error I get when running this query is
Unknown column 'DATA.User.userID' in 'where clause'
Sorry if this is badly explained. I will try and re-explain if need be.
You aren't creating new entries in the User table, you're updating existing ones. Hence, insert isn't the right syntax here, but rather update:
UPDATE DATA.User u
JOIN (SELECT uploaderID, SUM(num) AS sumNum
FROM INFO.Stories
GROUP BY uploadedID) i ON i.uploaderID = u.userID
SET numStories = sumNum
EDIT:
Some clarification, as requested in the comments.
The inner query sums the num in Stories per uploaderId. The updates statement updates the numStories in User the the calculated sum of the inner query of the matching id.

Complex MySQL Join with 3 tables and many2many relations

I have 3 tables person, account and subscription. Account belongs to Person as one to many and Account and Subscription are many to many.I need a sql which can select data from three tables.-
Person Tables
+----------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(128) | NO | | NULL | |
| password | varchar(128) | NO | | NULL | |
| account_id | int(11) | NO | | NULL | |
+----------------------------+---------------+------+---------------+----------------+
Account table
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| yearly_renew | tinyint(1) | NO | | NULL | |
| date_joined | date | NO | | NULL | |
| last_renewed | datetime | YES | | NULL | |
| signup | tinyint(1) | NO | | NULL | |
| reason | varchar(100) | YES | | NULL | |
| yearly_total | int(11) | YES | | NULL | |
| total | int(11) | YES | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
Account-Subscription table
+-----------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| account_id | int(11) | NO | MUL | NULL | |
| subscription_id | int(11) | NO | MUL | NULL | |
+-----------------+---------+------+-----+---------+----------------+
Subscription table
+-------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| subscription_type | varchar(150) | YES | | NULL | |
| hold | tinyint(1) | NO | | NULL | |
| start_date | date | YES | | NULL | |
| end_date | date | YES | | NULL | |
| amount_paid | double | YES | | NULL | |
| date_paid | date | YES | | NULL | |
| transaction_id | int(11) | YES | | NULL | |
| free | tinyint(1) | NO | | NULL | |
+-------------------+--------------+------+-----+---------+----------------+
Expecting output in a single query -
OUTPUT
+-----------+------------+--------------+
| person.id | account.id | subscription.id |
+-----------+------------+--------------+
| 10 | 11 | 20 |
| 15 | 32 | 45 |
| 23 | 43 | null |
+--------+---------+-----------------+
try this. it may works properly...
SELECT p.Id AS person.id
,p.account_id AS account.id
,acsub.subscription_id as subscription.id
FROM Person AS p
LEFT JOIN Account-Subscription AS acsub ON p.account_id=acsub.account_id
SELECT p.Id AS person.id
,p.account_id AS account.id
,acsub.subscription_id as subscription.id
FROM Person AS p
INNER JOIN
Account-Subscription AS acsub ON p.account_id=acsub.account_id

how to add a foreign key using an existing column in mysql

I have following table called transactions and I want to add foreign key using column account_id. But when I execute the query (see below) 0 rows affected. I am not getting what is wrong with the query.
I have two tables called transactions and accounts. Accounts table has an id as primary key and an account has_many transactions.
transactions table
+---------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| account_number | int(11) | YES | | NULL | |
| m_number | varchar(255) | YES | | NULL | |
| registration_number | varchar(255) | YES | | NULL | |
| page_number | varchar(255) | YES | | NULL | |
| entry_date | datetime | YES | | NULL | |
| narration | varchar(255) | YES | | NULL | |
| voucher_number | varchar(255) | YES | | NULL | |
| debit_credit | float | YES | | NULL | |
| profit | float | YES | | NULL | |
| account_code | int(11) | YES | | NULL | |
| balance | float | YES | | NULL | |
| branch | varchar(255) | YES | | NULL | |
| account_id | int(11) | YES | MUL | NULL | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+---------------------+--------------+------+-----+---------+----------------+
16 rows in set (0,01 sec)
mysql> ALTER TABLE transactions ADD FOREIGN KEY (account_id) REFERENCES accounts(id);
Query OK, 0 rows affected (0,03 sec)
Records: 0 Duplicates: 0 Warnings: 0
accounts table
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| account_number | int(11) | YES | | NULL | |
| account_code | int(11) | YES | | NULL | |
| branch | varchar(255) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
| father_name | varchar(255) | YES | | NULL | |
| nic_number | varchar(255) | YES | | NULL | |
| mohalla | varchar(255) | YES | | NULL | |
| village | varchar(255) | YES | | NULL | |
| nominee | varchar(255) | YES | | NULL | |
| relationship | varchar(255) | YES | | NULL | |
| opening_balance | float | YES | | NULL | |
| opening_date | datetime | YES | | NULL | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
After running the query shouldn't the column say F_K or something like PRI ?
Any help would be great. Thanks!