Query in Access (adding missing values) - sql

I've got two tables, Guides and Availability. Guides is a list of guides, and Availability is a list of dates for which information is known about a particular guide. For instance 03/03/14 - Guide 3 - Available or 05/03/14 - Guide 1 - Busy. If a guide's availability on a particular day isn't know yet, there isn't an entry in Availability at all for that day.
I want to write a query that will return a list of the statuses of all the guides during the next three days. If the status isn't known it will say Unknown.
I'm sure in SQL this task is definitely doable, but I am constrained by having to write a Web App in Access 2013. This means I must use the query editor in Access. Can anyone with expertise offer some guidance? If anything is unclear in the question, do say so.
Example query output:
03/03/2013 - Guide 1 - Busy
03/03/2013 - Guide 2 - Unknown
03/03/2013 - Guide 3 - Unknown
04/03/2013 - Guide 1 - Available
04/03/2013 - Guide 2 - Available
04/03/2013 - Guide 3 - Unknown
05/03/2013 - Guide 1 - Unknown
05/03/2013 - Guide 2 - Unknown
05/03/2013 - Guide 3 - Unknown
Table: Guides
Guide 1
Guide 2
Guide 3
Table: Availability
03/03/2013 - Guide 1 - Busy
04/03/2013 - Guide 1 - Available
04/03/2013 - Guide 2 - Available
P.S.: Someone has suggested I might need to make a third table listing all the dates for the next 10 years. This wouldn't be a problem if it helps with a solution

If you are limited to Access, you won't be able to use recursive CTE's (google it to find out about them, if interested).
therefore, you would have to create a table with all dates. Provided the table is called AllDates, and the date field is Dte, the query will look like this (you may need to filter by date range to limit the number of returned rows, otherwise you will see the records for all 10 years):
SELECT Availability.Dte, Availability.Guide, Availability.Status
FROM Availability INNER JOIN Guides ON Availability.Guide = Guides.Guide
UNION ALL
SELECT AllDates.Dte, Guides.Guide, 'Unknown' AS Status
FROM AllDates, Guides
WHERE NOT EXISTS (SELECT 1 FROM Availability WHERE Availability.Dte = AllDates.Dte And Availability.Guide = Guides.Guide)
ORDER BY 1, 2;
For the web-version of Access you will need to use 2 queries. The first one (DatesGuides) will list all guides for all dates, and its syntax is as simple as:
SELECT Guides.Guide, AllDates.Dte
FROM AllDates, Guides;
The second query will be LEFT JOINED with the first one. Its syntax is:
SELECT DatesGuides.Dte, DatesGuides.Guide, Nz([Status],'Unknown') AS Expr1
FROM Availability RIGHT JOIN DatesGuides ON Availability.Dte = DatesGuides.Dte AND Availability.Guide = DatesGuides.Guide;

Related

How to create Deltas in bigquery

I have a table in BQ which I refresh on daily basis. It's a full snapshot every day.
I have a business requirement to create deltas of that feed.
Table Details :
Table contains 10 columns
Out of 10 columns, 5 columns change on daily basis. How do I identify which columns changed and only create a snapshot for that?
For eg here are the columns in tableA: columns which will frequently change are in bold.
Custid - ABC
first_product - toy
first_product_purchase_date - 2015-01-01
last_product - ebook
last_product_purchase_date - 2018-05-01
second_product - Magazine
second_product_purchase_date - 2016-01-01
third_product - null
third_product_purchase_date - null
fourth_product - null
fourth_product_purchase_date - null
After more purchase Data will look like this:
Custid - ABC
first_product - toy
first_product_purchase_date - 2015-01-01
last_product - Hardbook
last_product_purchase_date - 2018-05-17
second_product - Magazine
second_product_purchase_date - 2016-01-01
third_product - CD
third_product_purchase_date - 2017-01-01
fourth_product - null
fourth_product_purchase_date - null
first_product = first product ever purchased
last_product = most recent product purchased
This is just one row of records for one customer. I have millions of customers with all these columns, and let's say half a million of the rows will be updated on daily basis.
In my delta, I just want the rows where any of the column value changed.
It seems like you have a column for each product bought and their repetition, perhaps this comes from a de-normalize dimensional models. To query the last "update" you would have to compare each columns the previous row by using the lead function. This would use a lot of computation and might not be optimal.
I recommend using repeated fields. The product and product_purchase_date would be repeated field and you could simply query using a where product_purchase_date = current_date() which would use much less computation.
De-normalize dimensional models are meant to use less computation on traditional data warehouses. Bigquery being fast, highly scalable, enterprise data warehouse has a lot of computing power.
To have a beter understanding on how BigQuery works under the hood I recommend reviewing this document.

SQL Access - Transpose Multiple results into one row

I am really struggling with the following problem as I am fairly new to SQL.
Problem: The projtask table has multiple tasks for 1 project. I need to transpose results so that I show all the statuses (e.g. task 150, 130, 110, 70 status) for every task on a single result row against 1 project.
At the moment I am coming back with multiple result rows against 1 project due to the number of tasks associated with that project. I hope this makes sense. If not please probe. Thanks, all the help would be appreciated :)
Ultimately I want the result to look like:
Project X - Task 10 - Status C - Task 130 - Status A - Task 150 - Status C
Project Y - Task 10 - Status A - Task 130 - Status C - Task 150 - Status A
Project Z - Task 10 - Status C - Task 130 - Status C - Task 150 - Status C
SELECT IIf(dbo_projtask.[task-num]=150 And dbo_projtask.stat='C','Released') AS 150_status, dbo_projtask.[proj-num],
IIf(dbo_projtask.[task-num]=130 And dbo_projtask.stat='A','Active') AS 130_status
FROM dbo_projtask
GROUP BY IIf(dbo_projtask.[task-num]=150 And dbo_projtask.stat='C','Released'), dbo_projtask.[proj-num],
IIf(dbo_projtask.[task-num]=130 And dbo_projtask.stat='A','Active');**
Not sure if i understand correctly, but trying to create columns for all tasks under a project doesn't sound like a scalable solution. Why not create an resultset with ProjectID, TaskID and StatusID and do any processing/modifications clietside? Relational databases tend to not like ragged/dynamic columns all that much. If you are absolutely set on the proposed structure you'd need to build a dynamic query that uses a pivot construction of sorts, but have my doubts whether it will work if you have a flexible number of tasks per project.

Parsing column data in SQL Syntax to an SQL Query

I am trying to solve a business flow issue at my work and I have an idea that I hope is technically feasible in SQL. What I would like to try and do is store different formulas in SQL syntax into database columns. Within SQL queries I would set variables to equal these columns so that the content of the columns is parsed as a part of the query and the different SQL statements pops up depending on the select specifications.
Short and sweet: I have some widgets to sell and whether or not a client can get these widgets depends on what other widgets they have bought, should have and shouldn’t have, country, customerid, their widget version, widget category and a couple of other things.
My question is how would someone proceed with this? I’m sure someone has made a similar setup before but which methods would be useful to study for my case? Are there case studies where I can find inspiration? I have searched for this without any luck. Hopefully someone who have solved similair issues before would be able to point me in a direction.
Thanks to whom‘ever is able to answer and has had the interest to read my post.
Best regards
Zaid
**OK this is more of a comment than an answer but the formatting doesn't work if I enter it as a comment!
To very vaguely answer your question I would have a Widgets table ie
WidgetID | Widget Name
1 Widget1
2 Widget2
3 Widget3
4 Widget4
Then have a WidgetRequirements table which is
WidgetRequiredID | WidgetID | RequiredWidgetID
1 1 2
2 1 3
3 1 4
4 2 4
5 3 1
6 3 4
This tells you that WidgetID 1 needs Widgets 2, 3 and 4 in order to be "active".
Widget 2 only needs widget4 to be active and Widget3 needs widgets 1 and 4.
This should get you started, expand on this theory.

SQL (Access): Multiple values per "ID" - Store as TRUE unless any FALSE

Good afternoon!
I have recently come across an issue that I am hoping can be solved with your help. Our system is [sadly] ran on Access (2007). I have decent experience with SQL and elect to use this method for most of queries rather than the Design View. However, this is the issue I have come across recently:
A table (with its own primary key of course) contains the ParticipantID and Records. This table may contain multiple records per person due to having events at various locations. With this information we track whether or not each record is within our system already due to the location falling under our large "umbrella" (Internal). To make it look simple, it looks something like this, ignoring the primary key as we only care about the participant ID.
ParticipantID Internal
1 -1
1 -1
2 0
3 -1
3 -1
3 0
4 -1
4 0
I want to be able to say if ANY of the records of a participant are not Internal (eg. =0), then in this query's results, store it as 0.
Hence, the results table would look something like:
ParticipantID Internal
1 -1
2 0
3 0
4 0
Does this make sense? Thank you in advance!
You can use Max:
SELECT internal.ParticipantID, Max(internal.Internal) AS MaxOfInternal
FROM internal
GROUP BY internal.ParticipantID;
I built the above using the query design window.
If the values Internal can be only 0 and -1 the following may help
Select ParticipantID,max(internal) from thetable
Group by ParticipantID

Locating all reachable nodes using SQL

Suppose a table with two columns: From and To. Example:
From To
1 2
2 3
2 4
4 5
I would like to know the most effective way to locate all nodes that are reachable from a node using a SQL Query. Example: given 1 it would return 2,3,4 and 5. It is possible to use several queries united by UNION clauses but it would limit the number of levels that can be reached. Perhaps a different data structure would make the problem more tractable but this is what is available.
I am using Firebird but I would like have a solution that only uses standard SQL.
You can use a recursive common table expression if you use most brands of database -- except for MySQL and SQLite and a few other obscure ones (sorry, I do consider Firebird obscure). This syntax is ANSI SQL standard, but Firebird doesn't support it yet.
Correction: Firebird 2.1 does support recursive CTE's, as #Hugues Van Landeghem comments.
Otherwise see my presentation Models for Hierarchical Data with SQL for several different approaches.
For example, you could store additional rows for every path in your tree, not just the immediate parent/child paths. I call this design Closure Table.
From To Length
1 1 0
1 2 1
1 3 2
1 4 2
1 5 3
2 2 0
2 3 1
2 4 1
3 3 0
4 4 0
4 5 1
5 5 0
Now you can query SELECT * FROM MyTable WHERE From = 1 and get all the descendants of that node.
PS: I'd avoid naming a column From, because that's an SQL reserved word.
Unfortunately there isn't a good generic solution to this that will work for all situations on all databases.
I recommend that you look at these resources for a MySQL solution:
Managing Hierarchical Data in MySQL
Models for hierarchical data - presentation by Bill Karwin which discusses this subject, demonstrates different solutions, and compares the adjacency list model you are using with other alternative models.
For PostgreSQL and SQL Server you should take a look at recursive CTEs.
If you are using Oracle you should look at CONNECT BY which is a proprietary extension to SQL that makes dealing with tree structures much easier.
With standard SQL the only way to store a tree with acceptable read performance is by using a hack such as path enumeration. Note that this is very heavy on writes.
ID PATH
1 1
2 1;2
3 1;2;3
4 1;2;4
SELECT * FROM tree WHERE path LIKE '%2;%'