Selecting Available Items Based on Date Range Availability - mysql

I know questions of this type have been asked here, but wondering if this scenario is do-able (I didn't see other examples of this).
Let's say I have a MySQL DB table that has the following items:
item | type
----------------
1 | Small
2 | Small
3 | Large
4 | Small
And I have an order table where an end-user can "check-out" these items for a date range that he/she specifies (sort of like booking a hotel room):
orderid | item | startdate | enddate
--------------------------------------------
1 2,4 2015-08-15 2015-09-15
Potentially, there can be thousands of items, and anyone can choose to reserve a large number at once if desired. This is why I represent item as a string 2,4 in the order table example above.
Assuming the end-user were to pick a date range within the orderid's date range, how can I do a MySQL query that only shows items which are available outside the start/end date range when I represent the item as a string in the order table? Would this be possible?

Related

SSRS Report - Horizontally Sort Columns Across Column Groups

I am creating an unusual SSRS report that requires that the user be able to use parameters to select which of the (more than 250) fields appear in the report. So the number of columns in this report can vary greatly.
I've been mostly successful at implementing this, but am stuck at controlling how to change the order of the columns.
Here is (a simplified example) of my original data:
My data as a screen capture
CompanyID | Address | Website_URL | Date_Created | Date Modified |
1 |123 Main Street|www.fake.com | 3/14/2019 | 3/15/2019 |
2 |555 Park Ave |www.notreal.com|3/12/2019 | 3/13/2019 |
The first thing I've done is to unpivot my data within my dataset (i used cross apply to do this). The name of what the column used to be is kept in a column named something like "Col_1", and the value is kept in a column named something like "Val_1". The trick is, I have to do this multiple times, once for each data type that I'm dealing with. Because obviously you can't have dates and nvarchars in the same column. When I unpivot the data above, it looks like this:
CompanyID | Col_1 | Val_1 | Col_2 | Val_2 |
1 |Address |123 Main Street | Date_Created | 3/14/2019 |
1 |Website_URL |www.fake.com |Date Modified | 3/15/2019 |
2 |Address |555 Park Ave |Date_Created |3/12/2019 |
2 |Website_URL |www.notreal.com |Date Modified |3/13/2019 |
The point in doing this is now I can create a matrix is the SSRS report with the CompanyID as a row group. Then I create two adjacent column groups for Col_1, and Col_2, which have as their values Val_1 and Val_2, respectively.
Click here to see SSRS Groupings
Now, when this report runs, each column group (for example, Col_1) expands out to show all the column names I had under that column in my unpivoted data. This could be dozens of columns. This picture shows what my final data looks like. This is similar to what my original data looked like. But with the benefit of the fact that the columns are being displayed dynamically.
My resulting Matrix
So, the only problem I'm having is that the columns are stuck within their groups. Say I want to sort them alphabetically, I can only sort the nvarchars together, and the dates together. I cannot sort the across their groups. Is there a way I can do this?
The resulting Matrix I want, with columns sorted alphabetically
Thanks in advance for any ideas.
Using your original unpivoted data, the design of your report needs to have 4 column groups.
1.Address
2.Date created
3.Date modified
4.Website URL

Autoincrement non-unique column

I am trying to create a queue system for pre-orders for our webshop. Sometimes we have more orders than stock for a few deliveries to our warehouse and I'm trying to organize so that the people that made the orders first gets their products first.
The problem comes when a customer wants to make a change to an order, by for example adding something to it. For booking purposes we then make a return of the first order to our system which creates another order, and then finally create a new order with everything on it. This causes this customer to be last in the queue list in our current system where we go by date created.
What I would like to do is to have the original queue spot be copied over to the new order without messing up the autoincrementing. This also means that there will be three orders (Original, plus return, plus new) with the same number.
id | order | queue | ordercomment
1 | 1001 | 1 | new order
2 | 1002 | 2 | new order
3 | 1003 | 3 | new order
4 | 1004 | 1 | return order 1001
5 | 1005 | 1 | corrected order 1001
6 | 1006 | 4 | new order
Is there any way to handle this without making a manual incrementing solution that checks for the current highest number whenever an order is made?
where we go by date created
But your data has no such date. You're relying on incrementing integers to determine the sort order, and that's where you're running into trouble.
If you want to sort by the date created, store the date the order was created. Any time you modify, append, or otherwise recreate an order you can still preserve the original order date. Perhaps with two columns, the date of the current order and the date of the original order. (For most orders these two values would be the same, but there's nothing wrong with that.)
Then your order of priority would simply be the date of the original order.
Basically, don't try to use an integer as a timestamp. Use a timestamp.

Better database basis for table with multiple date informations

What do you think is the better basis, in sense of "easyer to use" with SQL Syntax - the first or the second table?
Please give reasons.
table one:
+----+--------------------------------------+
| id | date1 | date2 | date3 |
+----+------------+------------+------------+
| 1 | 2014-02-15 | 2014-03-24 | 2014-03-24 |
| 2 | NULL | NULL | 2014-08-15 |
| 3 | 2014-06-13 | NULL | NULL |
| 4 | 2014-01-10 | 2014-09-14 | 2014-01-12 |
+----+------------+------------+------------+
table two:
+----+------------+-------+-------+-------+
| id | date | one | two | three |
+----+------------+-------+-------+-------+
| 1 | 2015-07-04 | true | true | false |
| 2 | 2014-06-13 | false | true | false |
| 3 | 2014-11-11 | true | false | false |
| 4 | 2017-03-02 | false | true | true |
+----+------------+-------+-------+-------+
(content of tables doesn't match in this example)
I just want to know if it is easier to deal with when you have just one date field and additional boolean fields instead of multiple date fields. For example if you want to have SELECTs like this
That depends what the dates are.
Just because two fields are both dates tell us nothing about what they have to do with each other, if anything.
If the three dates are totally unrelated and would never be interchangeable in processing, and if they are a fixed set that is not likely to change frequently, like "birth date", "hire date", and "next annual review date", then I would just make them three separate fields. Then when you write queries it would be very straightforward, like
select employee_id, name from employee where next_annual_review_date='2015-02-01'
On the other hand, if you might quite reasonably write a query that would search all three dates, then it makes sense to break the dates out into another table, with a field that identifies the specific date. Like I created a table once for a warehouse system where there were many dates associated with a stock item -- the date it arrived in the warehouse, the date it was sold, inventoried, returned to the warehouse (because the customer returned it, for example), re-sold, lost, damaged, repaired, etc. These dates could come in many possible orders, and many of them could occur multiple times. Like an item might be damaged, repaired, and then damaged and repaired again, or it could be sold, returned, sold again, and returned again, etc. So I created a table for the stock item with the "static" info like part number, description, and the bazillion codes that the user needed to describe the item, and then a separate "stock event" table with the stock item id, event code, the date, and various other stuff. Then there was another stock event table that listed the event codes with descriptions.
This made it easy to construct queries like, "List everything that has happened to this item in the past four years in date order", or "list all items added to the inventory in November", etc.
Your second table seems like an all-around bad idea. I can't think of any advantage to having 3 Boolean fields rather than one field that says what it is. Suppose the three dates are birth date, hire date, and next review date. You could create codes for these -- maybe 1,2, 3; maybe B, H, R; whatever. Then selecting on a specific event is easy enough either way, I guess: select date where hire = true versus select date where event = 'H'.
But listing multiple dates with a description is much easier with a code. You just need a table of codes and descriptions, and then you write
select employee_name, event_code, date
from employee e
join employee_event ev on ev.employee_id=e.employee_id
join event v on v.event_id=ev.event_id
where ... whatever ...
But with the Booleans, you'd need a three-way case/when.
What happens when new event types are added? With an event code, it's just a data change: add a enw record to the event code table. With the Booleans, you need to change the database.
You create the potential for ambiguous data. What happens if two of the Booleans are true, or if none of them are true? What does that mean? There's a whole category of error that can't possibly happen with event codes.
Neither of those are normalized. Normalization is a good way to avoid data anomalies and keep things DRY.
What do your dates represent? What does "one", "two", and "three" represent?
I would go with something like this:
create table my_table (
my_table_id int primary key,
a_more_descriptive_word_than_date date not null,
label text not null
);
The data would look like this:
id date label
1 2014-12-23 one
2 2014-12-24 two
3 2014-12-25 three

mysql lookup table

Lookup table - unique row identity
The other lookup tables just do not make sense as from what I have seen giving a row an ID then putting that id in another table which also has a id then adding these id's to some more tables which may reference them and still creating a lookup tables with more id's (this is how all the examples I can find seem) What I have done is this :
product_item - table
------------------------------------------
id | title | supplier | price
1 | title11 | suuplier1 | price1
etc.
it then goes on to include more items (sure you get it)
product_feature - table
--------------------------
id | title | iskeyfeature
1 | feature1 | true
feature_desc - table
-----------------------------
id | title | desc
1 | desc1 | text description
product_lookup - table
item_id | feature_id | feature_desc
1 | 1 | 1
1 | 2 | 2
1 | 3 | 3
1 |64 | 15
(as these only need to be referenced in the lookup the id's can be multiples per item or multiple items per feature)
What I want to do without adding item_id to every feature row or description row is retrieve only the columns from the multiple tables where their id is referenced in the same row of the lookup table. I want to know if it is possible to select all the referenced columns from the lookup row if I only know the item_id eg. Item_id = 1 return all rows where item_id = 1 with the columns referenced in the same row. Every item can have multiple features and also every feature could be attached to multiple items , this will not matter if I can just get the pattern right in how to construct this query from a single known value.
Any assistance or just some direction will be greatly appreciated. I'm using phpmyadmin, and sure this will be easier with some php voodoo I am learning mysql from tutorials ect and would like to know how to do it with sql directly.
Having a NULL value in a column is not the major concern that would lead to this design - it's the problem with adding new attribute columns in the future, at which MySQL is disgracefully bad.
If you want to make a query that returns everything about an item in one row, you need to LEFT OUTER JOIN back to the product_lookup table for each feature_id. This is about every 10th mysql question on Stack Overflow, so you should be able to find tons of examples.

Database Design for Historical Aggregation

I am trying to decide which would be the best data warehouse type design. It will be used to find historical price averages of different item during different time periods using a Google type search. For example, what was the avg price of Stock A this month, 3m, 6m, and 1 year ago? The issue is that I do not have an item name that I can use, I have descriptions fields about the item.
This means that I can't aggregate items into views, since the same item maybe listed 20 times each with different descriptions, so I have to on the fly do a full-text search on the description field, grab the price where the insertdate is < 3 months ago. Then find the average of that.
So is my best bet to have everything in one table like:
MAIN
----------------------------
ID | Description | Price | Date
or many tables:
DESCRIPTION
------------------
ID | Description |
PRICE
---------
ID | PRICE
And just join to get the data I want. The database will contain a few million rows. If I had a way to get the real name of the item I could see pre aggregating the data, but that is not an option for me. I appreciate any advice!
I'd say option 2 ... keep the top level details in the "description" table. And the historic data in the "price" table (albeit, with a Date field added to capture the temporal value)
As Joel suggested, Option 2 is likely going to provide you more flexibility. I would suggest including additional dates in each table to accomodate for slowly changing dimensions. Descriptions and other attributes about a given item may change over time.
In the case of a brick and mortar retailer, you would quite likely include the Store ID as well because items are quite likely priced differently in different locations due to competition and demographic make-up of your customers near a given location.
DESCRIPTION
---------------------------------------------------
ID | Description | Effective Date | Expiration Date
PRICE
-----------------------------------------------------------
ID | Location ID | Price | Effective Date | Expiration Date