Working Through Normalization (3NF) - database

I've been planning this website for a while now and began putting it together a few weeks ago and I'd say that things were going extremely well until the other day I was introduced to normalization. It's taken me quite some time to get the hang of what it is and why it's needed but I think that I'm close to acheiving my overall goal now.
So the scenario is that I have a website where members can join and set up their own newspaper/blog and assign authors to it. The site primarily consists of a members_table, authors_table, newspapers_table and posts_table, which I've gone through and normalized to get:
Members
+----+-----------+----------+-----------------+----------+----------+------------+------------+
| ID | FIRSTNAME | SURNAME | EMAIL | USERNAME | PASSWORD | AVATAR | JOINED |
+----+-----------+----------+-----------------+----------+----------+------------+------------+
| 01 | Brian | Griffin | brian#gmail.com | briang | *** | hdhs.jpg | 2014-07-31 |
| 02 | Meg | Griffin | meg#gmail.com | megg | *** | | 2014-07-31 |
| 03 | Peter | Griffin | peter#gmail.com | peterg | *** | jaunsq.jpg | 2014-07-31 |
| 04 | Glen | Quagmire | glen#gmail.com | glen | *** | | 2014-07-31 |
+----+-----------+----------+-----------------+----------+----------+------------+------------+
Authors
+----+-----------+----------+-----------------+-------------------+---------+----------+---------+
| ID | FIRSTNAME | SURNAME | EMAIL | BIO ( REQUIRED ) | TWITTER | FACEBOOK | WEBSITE |
+----+-----------+----------+-----------------+-------------------+---------+----------+---------+
| 01 | Brian | Griffin | brian#gmail.com | About me... | URL | | URL |
| 02 | Meg | Griffin | meg#gmail.com | About me... | URL | | |
| 03 | Peter | Griffin | peter#gmail.com | About me... | | URL | URL |
| 04 | Glen | Quagmire | glen#gmail.com | About me... | URL | URL | |
+----+-----------+----------+-----------------+-------------------+---------+----------+---------+
** Should Socials Be Broken Down Here? If So, How?
Newspaper_Categories
+----+-------------------+
| ID | CATEGORY |
+----+-------------------+
| 01 | Lifestyle |
| 02 | Auto Mobiles |
| 03 | Entertainment |
| 04 | Food & Drink |
| 05 | Internet |
+----+-------------------+
Newspapers
+----+-----------------------+----------+---------+------------------+------------------+
| ID | NAME | CATEGORY | AVATAR | BIO ( REQUIRED ) | OWNER ( MEMBER ) |
+----+-----------------------+----------+---------+------------------+------------------+
| 01 | Spooner Street Weekly | 01 | 311.jpg | About Us... | 01 |
| 02 | A Dogs Life | 01 | | About Us... | 01 |
| 03 | In The Kitchen | 04 | js.jpg | About Us... | 02 |
+----+-----------------------+----------+---------+------------------+------------------+
Should Owner go Here or in a table named Newspaper_Owners
Socials
+----+-------------------+
| ID | TYPE |
+----+-------------------+
| 01 | Facebook |
| 02 | Twitter |
| 03 | Google |
| 04 | Flickr |
| 05 | Youtube |
+----+-------------------+
Newspaper_Socials
+----------+--------+------+
| NEWSAPER | SOCIAL | LINK |
+----------+--------+------+
| 01 | 01 | URL |
| 01 | 02 | URL |
| 01 | 05 | URL |
| 01 | 01 | URL |
| 02 | 02 | URL |
| 02 | 04 | URL |
| 03 | 01 | URL |
+----------+--------+------+
Post_Categories
+-------------------+--------------------+
| ID | NEWSPAPER_ID | CATEGORY |
+----+--------------+--------------------+
| 01 | 01 | Glens Girls |
| 02 | 01 | In The Clam |
| 03 | 01 | Peters Shenanigans |
| 04 | 02 | Martini Recipes |
| 05 | 03 | Housewife Tips |
+----+--------------+--------------------+
Posts
+----+----------+-------+---------+----------+------------+-------+
| ID | CATEGORY | TITLE | ARTICLE | FEATURED | ADDED | VIEWS |
+----+----------+-------+---------+----------+------------+-------+
| 01 | 01 | Title | Article | 0 | 2014-07-31 | 200 |
| 02 | 01 | Title | Article | 0 | 2014-07-31 | 220 |
| 03 | 03 | Title | Article | 1 | 2014-07-31 | 232 |
| 04 | 05 | Title | Article | 0 | 2014-07-31 | 143 |
| 05 | 05 | Title | Article | 1 | 2014-07-31 | 311 |
+----+----------+-------+---------+----------+------------+-------+
Post_Photos
+---------+-----+--------------+------+
| POST_ID | ALT | PHOTOGRAPHER | LINK |
+---------+-----+--------------+------+
| 01 | Alt | John Smith | URL |
| 02 | Alt | | |
| 03 | Alt | Mike Jones | |
| 05 | Alt | Adam West | URL |
+---------+-----+--------------+------+
Post_Keywords
+---------+---------+
| POST_ID | KEYWORD |
+---------+---------+
| 01 | Keyword |
| 01 | Keyword |
| 01 | Keyword |
| 01 | Keyword |
| 02 | Keyword |
| 02 | Keyword |
| 03 | Keyword |
| 03 | Keyword |
| 03 | Keyword |
+---------+---------+
If each post is only allowed 3 keywords, can these be added to the end of Posts table?
Author_Posts
+-----------+---------+
| AUTHOR_ID | POST_ID |
+-----------+---------+
| 01 | 01 |
| 01 | 02 |
| 01 | 03 |
| 02 | 04 |
| 03 | 05 |
+-----------+---------+
Could anyone please let me know if I'm on the right lines with this structure and give me some pointers on where Primary Keys and also Foreign Keys ??? should go?

"** Should Socials Be Broken Down Here? If So, How?"
Yes, you already have the socials table.
Add a new many to many table of Users to Socials

Related

Pyspark Dataframe Iterate Array Columns

In PySpark, I have a dataframe I'm trying to parse multiple columns with arrays. The last two rows in the dataframe contains multiple values I would like to parse into separate rows.
+-------------+---------------+-------------+--------------------+--------------+-------------+----------------------+--------------+
| WB-API-CNTY | WB-API-UNIQUE | WB-OIL-CODE | WB-OIL-LSE-NBR | WB-OIL-DIST | WB-GAS-CODE | WB-GAS-RRC-ID | WB-GAS-DIS |
+-------------+---------------+-------------+--------------------+--------------+-------------+----------------------+--------------+
| 449 | 80212 | [] | [] | [] | [] | [] | [] |
+-------------+---------------+-------------+--------------------+--------------+-------------+----------------------+--------------+
| 449 | 80214 | ["O"] | ["05361"] | ["06"] | ["O"] | ["060536"] | ["00"] |
+-------------+---------------+-------------+--------------------+--------------+-------------+----------------------+--------------+
| 449 | 80222 | ["O", "O"] | ["01718", "05492"] | ["06", "06"] | ["O", "O"] | ["060171", "060549"] | ["00", "00"] |
+-------------+---------------+-------------+--------------------+--------------+-------------+----------------------+--------------+
| 451 | 00005 | ["G", "O"] | ["5568", "04351"] | ["10", "09"] | ["G", "O"] | ["105568", "090435"] | ["09", "00"] |
+-------------+---------------+-------------+--------------------+--------------+-------------+----------------------+--------------+
Results:
+-------------+---------------+-------------+----------------+-------------+-------------+---------------+------------+
| WB-API-CNTY | WB-API-UNIQUE | WB-OIL-CODE | WB-OIL-LSE-NBR | WB-OIL-DIST | WB-GAS-CODE | WB-GAS-RRC-ID | WB-GAS-DIS |
+-------------+---------------+-------------+----------------+-------------+-------------+---------------+------------+
| 449 | 80212 | | | | | | |
+-------------+---------------+-------------+----------------+-------------+-------------+---------------+------------+
| 449 | 80214 | O | 05361 | 06 | O | 060536 | 00 |
+-------------+---------------+-------------+----------------+-------------+-------------+---------------+------------+
| 449 | 80222 | O | 01718 | 06 | O | 060171 | 00 |
+-------------+---------------+-------------+----------------+-------------+-------------+---------------+------------+
| 449 | 80222 | O | 05492 | 06 | O | 060549 | 00 |
+-------------+---------------+-------------+----------------+-------------+-------------+---------------+------------+
| 451 | 00005 | G | 5568 | 10 | G | 105568 | 09 |
+-------------+---------------+-------------+----------------+-------------+-------------+---------------+------------+
| 451 | 00005 | O | 04351 | 09 | O | 090435 | 00 |
+-------------+---------------+-------------+----------------+-------------+-------------+---------------+------------+
array_cols = ['WB-OIL-CODE', 'WB-OIL-LSE-NBR', 'WB-OIL-DIST', 'WB-GAS-CODE', 'WB-GAS-RRC-ID', 'WB-GAS-DIS']
other_cols = [c for c in df.columns if c not in array_cols]
df = df.select(
*other_cols,
F.expr(f"inline(arrays_zip({'`' + '`,`'.join(array_cols) + '`'}))")
)

I can't apply multiple conditions in this SQL statement

I don't know why it doesn't give me the answer for students enrolled in Database Systems but not in Operating System Design.
select student.snum, student.sname, enrolled.cname
-> from enrolled
-> inner join student ON enrolled.snum = student.snum
-> where enrolled.cname="Database Systems" AND enrolled.cname<>"Operating System Design";`
+-----------+--------------------+------------------+
| snum | sname | cname |
+-----------+--------------------+------------------+
| 112348546 | Joseph Thompson | Database Systems |
| 115987938 | Christopher Garcia | Database Systems |
| 348121549 | Paul Hall | Database Systems |
| 322654189 | Lisa Walker | Database Systems |
| 552455318 | Ana Lopez | Database Systems |
+-----------+--------------------+------------------+
My student table.
+-----------+--------------------+------------------------+-------+------+
| snum | sname | major | level | age |
+-----------+--------------------+------------------------+-------+------+
| 51135593 | Maria White | English | SR | 21 |
| 60839453 | Charles Harris | Architecture | SR | 22 |
| 99354543 | Susan Martin | Law | JR | 20 |
| 112348546 | Joseph Thompson | Computer Science | SO | 19 |
| 115987938 | Christopher Garcia | Computer Science | JR | 20 |
| 132977562 | Angela Martinez | History | SR | 20 |
| 269734834 | Thomas Robinson | Psychology | SO | 18 |
| 280158572 | Margaret Clark | Animal Science | FR | 18 |
| 301221823 | Juan Rodriguez | Psychology | JR | 20 |
| 318548912 | Dorthy Lewis | Finance | FR | 18 |
| 320874981 | Daniel Lee | Electrical Engineering | FR | 17 |
| 322654189 | Lisa Walker | Computer Science | SO | 17 |
| 348121549 | Paul Hall | Computer Science | JR | 18 |
| 351565322 | Nancy Allen | Accounting | JR | 19 |
| 451519864 | Mark Young | Finance | FR | 18 |
| 455798411 | Luis Hernandez | Electrical Engineering | FR | 17 |
| 462156489 | Donald King | Mechanical Engineering | SO | 19 |
| 550156548 | George Wright | Education | SR | 21 |
| 552455318 | Ana Lopez | Computer Engineering | SR | 19 |
| 556784565 | Kenneth Hill | Civil Engineering | SR | 21 |
| 567354612 | Karen Scott | Computer Engineering | FR | 18 |
| 573284895 | Steven Green | Kinesiology | SO | 19 |
| 574489456 | Betty Adams | Economics | JR | 20 |
| 578875478 | Edward Baker | Veterinary Medicine | SR | 21 |
+-----------+--------------------+------------------------+-------+------+
My enrolled table
+-----------+----------------------------+
| snum | cname |
+-----------+----------------------------+
| 112348546 | Database Systems |
| 115987938 | Database Systems |
| 348121549 | Database Systems |
| 322654189 | Database Systems |
| 552455318 | Database Systems |
| 455798411 | Operating System Design |
| 552455318 | Operating System Design |
| 567354612 | Operating System Design |
| 112348546 | Operating System Design |
| 115987938 | Operating System Design |
| 322654189 | Operating System Design |
| 567354612 | Data Structures |
| 552455318 | Communication Networks |
| 455798411 | Optical Electronics |
| 301221823 | Perception |
| 301221823 | Social Cognition |
| 301221823 | American Political Parties |
| 556784565 | Air Quality Engineering |
| 99354543 | Patent Law |
| 574489456 | Urban Economics |
+-----------+----------------------------+
You need to use the NOT EXISTS as follows:
select s.snum, s.sname, e.cname
from enrolled e
inner join student s ON e.snum = s.snum
where e.cname='Database Systems'
AND not exists
(select 1 from enrolled ee
where ee.snum = e.snum and e.cname = 'Operating System Design');
Compare string with single quotation mark(' ') than double quotation(" "). Your code seems ok to me.
Remember:
Single quotes are for strings.
Double quotes are for tables names and column names.
select student.snum, student.sname, enrolled.cname
from enrolled
inner join student ON enrolled.snum = student.snum
where enrolled.cname='Database Systems'
AND enrolled.cname<>'Operating System Design';
or try this
select student.snum, student.sname, enrolled.cname
from enrolled
inner join student ON enrolled.snum = student.snum
where enrolled.cname='Database Systems'

Why using char type as index for looping gives unexpected results?

Bear in mind this is an old version of the C compiler: CP/M for Z80.
#include<stdio.h>
main()
{
char i = 0;
do
{
printf("0x%04x | ", i);
} while (++ i);
}
Expected:
0x0000 | 0x0001 | 0x0002 | 0x0003 | 0x0004 | 0x0005 | 0x0006 | 0x0007 | 0x0008 | 0x0009 | 0x000A | 0x000B | 0x000C | 0x000D | 0x000E | 0x000F | 0x0010 | 0x0011 | 0x0012 | 0x0013 | 0x0014 | 0x0015 | 0x0016 | 0x0017 | 0x0018 | 0x0019 | 0x001A | 0x001B | 0x001C | 0x001D | 0x001E | 0x001F | 0x0020 | 0x0021 | 0x0022 | 0x0023 | 0x0024 | 0x0025 | 0x0026 | 0x0027 | 0x0028 | 0x0029 | 0x002A | 0x002B | 0x002C | 0x002D | 0x002E | 0x002F | 0x0030 | 0x0031 | 0x0032 | 0x0033 | 0x0034 | 0x0035 | 0x0036 | 0x0037 | 0x0038 | 0x0039 | 0x003A | 0x003B | 0x003C | 0x003D | 0x003E | 0x003F | 0x0040 | 0x0041 | 0x0042 | 0x0043 | 0x0044 | 0x0045 | 0x0046 | 0x0047 | 0x0048 | 0x0049 | 0x004A | 0x004B | 0x004C | 0x004D | 0x004E | 0x004F | 0x0050 | 0x0051 | 0x0052 | 0x0053 | 0x0054 | 0x0055 | 0x0056 | 0x0057 | 0x0058 | 0x0059 | 0x005A | 0x005B | 0x005C | 0x005D | 0x005E | 0x005F | 0x0060 | 0x0061 | 0x0062 | 0x0063 | 0x0064 | 0x0065 | 0x0066 | 0x0067 | 0x0068 | 0x0069 | 0x006A | 0x006B | 0x006C | 0x006D | 0x006E | 0x006F | 0x0070 | 0x0071 | 0x0072 | 0x0073 | 0x0074 | 0x0075 | 0x0076 | 0x0077 | 0x0078 | 0x0079 | 0x007A | 0x007B | 0x007C | 0x007D | 0x007E | 0x007F | 0x0080 | 0x0081 | 0x0082 | 0x0083 | 0x0084 | 0x0085 | 0x0086 | 0x0087 | 0x0088 | 0x0089 | 0x008A | 0x008B | 0x008C | 0x008D | 0x008E | 0x008F | 0x0090 | 0x0091 | 0x0092 | 0x0093 | 0x0094 | 0x0095 | 0x0096 | 0x0097 | 0x0098 | 0x0099 | 0x009A | 0x009B | 0x009C | 0x009D | 0x009E | 0x009F | 0x00A0 | 0x00A1 | 0x00A2 | 0x00A3 | 0x00A4 | 0x00A5 | 0x00A6 | 0x00A7 | 0x00A8 | 0x00A9 | 0x00AA | 0x00AB | 0x00AC | 0x00AD | 0x00AE | 0x00AF | 0x00B0 | 0x00B1 | 0x00B2 | 0x00B3 | 0x00B4 | 0x00B5 | 0x00B6 | 0x00B7 | 0x00B8 | 0x00B9 | 0x00BA | 0x00BB | 0x00BC | 0x00BD | 0x00BE | 0x00BF | 0x00C0 | 0x00C1 | 0x00C2 | 0x00C3 | 0x00C4 | 0x00C5 | 0x00C6 | 0x00C7 | 0x00C8 | 0x00C9 | 0x00CA | 0x00CB | 0x00CC | 0x00CD | 0x00CE | 0x00CF | 0x00D0 | 0x00D1 | 0x00D2 | 0x00D3 | 0x00D4 | 0x00D5 | 0x00D6 | 0x00D7 | 0x00D8 | 0x00D9 | 0x00DA | 0x00DB | 0x00DC | 0x00DD | 0x00DE | 0x00DF | 0x00E0 | 0x00E1 | 0x00E2 | 0x00E3 | 0x00E4 | 0x00E5 | 0x00E6 | 0x00E7 | 0x00E8 | 0x00E9 | 0x00EA | 0x00EB | 0x00EC | 0x00ED | 0x00EE | 0x00EF | 0x00F0 | 0x00F1 | 0x00F2 | 0x00F3 | 0x00F4 | 0x00F5 | 0x00F6 | 0x00F7 | 0x00F8 | 0x00F9 | 0x00FA | 0x00FB | 0x00FC | 0x00FD | 0x00FE | 0x00FF |
Actual:
0x0A00 | 0x0A01 | 0x0A02 | 0x0A03 | 0x0A04 | 0x0A05 | 0x0A06 | 0x0A07 | 0x0A08 | 0x0A09 | 0x0A0A | 0x0A0B | 0x0A0C | 0x0A0D | 0x0A0E | 0x0A0F | 0x0A10 | 0x0A11 | 0x0A12 | 0x0A13 | 0x0A14 | 0x0A15 | 0x0A16 | 0x0A17 | 0x0A18 | 0x0A19 | 0x0A1A | 0x0A1B | 0x0A1C | 0x0A1D | 0x0A1E | 0x0A1F | 0x0A20 | 0x0A21 | 0x0A22 | 0x0A23 | 0x0A24 | 0x0A25 | 0x0A26 | 0x0A27 | 0x0A28 | 0x0A29 | 0x0A2A | 0x0A2B | 0x0A2C | 0x0A2D | 0x0A2E | 0x0A2F | 0x0A30 | 0x0A31 | 0x0A32 | 0x0A33 | 0x0A34 | 0x0A35 | 0x0A36 | 0x0A37 | 0x0A38 | 0x0A39 | 0x0A3A | 0x0A3B | 0x0A3C | 0x0A3D | 0x0A3E | 0x0A3F | 0x0A40 | 0x0A41 | 0x0A42 | 0x0A43 | 0x0A44 | 0x0A45 | 0x0A46 | 0x0A47 | 0x0A48 | 0x0A49 | 0x0A4A | 0x0A4B | 0x0A4C | 0x0A4D | 0x0A4E | 0x0A4F | 0x0A50 | 0x0A51 | 0x0A52 | 0x0A53 | 0x0A54 | 0x0A55 | 0x0A56 | 0x0A57 | 0x0A58 | 0x0A59 | 0x0A5A | 0x0A5B | 0x0A5C | 0x0A5D | 0x0A5E | 0x0A5F | 0x0A60 | 0x0A61 | 0x0A62 | 0x0A63 | 0x0A64 | 0x0A65 | 0x0A66 | 0x0A67 | 0x0A68 | 0x0A69 | 0x0A6A | 0x0A6B | 0x0A6C | 0x0A6D | 0x0A6E | 0x0A6F | 0x0A70 | 0x0A71 | 0x0A72 | 0x0A73 | 0x0A74 | 0x0A75 | 0x0A76 | 0x0A77 | 0x0A78 | 0x0A79 | 0x0A7A | 0x0A7B | 0x0A7C | 0x0A7D | 0x0A7E | 0x0A7F | 0x0A80 | 0x0A81 | 0x0A82 | 0x0A83 | 0x0A84 | 0x0A85 | 0x0A86 | 0x0A87 | 0x0A88 | 0x0A89 | 0x0A8A | 0x0A8B | 0x0A8C | 0x0A8D | 0x0A8E | 0x0A8F | 0x0A90 | 0x0A91 | 0x0A92 | 0x0A93 | 0x0A94 | 0x0A95 | 0x0A96 | 0x0A97 | 0x0A98 | 0x0A99 | 0x0A9A | 0x0A9B | 0x0A9C | 0x0A9D | 0x0A9E | 0x0A9F | 0x0AA0 | 0x0AA1 | 0x0AA2 | 0x0AA3 | 0x0AA4 | 0x0AA5 | 0x0AA6 | 0x0AA7 | 0x0AA8 | 0x0AA9 | 0x0AAA | 0x0AAB | 0x0AAC | 0x0AAD | 0x0AAE | 0x0AAF | 0x0AB0 | 0x0AB1 | 0x0AB2 | 0x0AB3 | 0x0AB4 | 0x0AB5 | 0x0AB6 | 0x0AB7 | 0x0AB8 | 0x0AB9 | 0x0ABA | 0x0ABB | 0x0ABC | 0x0ABD | 0x0ABE | 0x0ABF | 0x0AC0 | 0x0AC1 | 0x0AC2 | 0x0AC3 | 0x0AC4 | 0x0AC5 | 0x0AC6 | 0x0AC7 | 0x0AC8 | 0x0AC9 | 0x0ACA | 0x0ACB | 0x0ACC | 0x0ACD | 0x0ACE | 0x0ACF | 0x0AD0 | 0x0AD1 | 0x0AD2 | 0x0AD3 | 0x0AD4 | 0x0AD5 | 0x0AD6 | 0x0AD7 | 0x0AD8 | 0x0AD9 | 0x0ADA | 0x0ADB | 0x0ADC | 0x0ADD | 0x0ADE | 0x0ADF | 0x0AE0 | 0x0AE1 | 0x0AE2 | 0x0AE3 | 0x0AE4 | 0x0AE5 | 0x0AE6 | 0x0AE7 | 0x0AE8 | 0x0AE9 | 0x0AEA | 0x0AEB | 0x0AEC | 0x0AED | 0x0AEE | 0x0AEF | 0x0AF0 | 0x0AF1 | 0x0AF2 | 0x0AF3 | 0x0AF4 | 0x0AF5 | 0x0AF6 | 0x0AF7 | 0x0AF8 | 0x0AF9 | 0x0AFA | 0x0AFB | 0x0AFC | 0x0AFD | 0x0AFE | 0x0AFF |
What am I doing wrong?
Assembly:
cseg
?59999:
defb 48,120,37,48,52,120,32,124,32,0
main#:
ld c,0
#0:
push bc
push bc
ld bc,?59999
push bc
ld hl,2
call printf
pop bc
pop bc
pop bc
inc c
jp nz,#0
ret
public main#
extrn printf
end
Golly. LONG time since I used a z80 C compiler, and most were buggy as [unprintable] back then.
I would suggest that you dump the assembler if the compiler allows. My GUESS is that internally the char is being promoted to a 16 bit INT with indeterminate upper bits set.
The problem is that %04X expects an integer - not a char.
You might try forcing the compiler to play nice by explicitly casting the char to an int - i.e.
printf("0x%04x | ", (int) i);
Most probable thing is that, as being an old 8 bit compiler, it is not converting the char typed i variable into an int and it is just pushing the bc register (assuming your function will not use the high part, which is simply not true, as your function (printf()) expects a whole int as parameter) which you don't know what it has in the b register. The compiler is using the full bc register to print, as you use %x format, which is for an int parameter, and this explains the presence of the high byte as 0x0a in the output (and which doesn't appear anywhere in your assembler listing). Later versions of the standard begun to convert every short and char arguments to int in order probably to avoid this kind of issue.
Try this code, and see if that solves the problem.
#include<stdio.h>
main()
{
char i = 0;
do
{
printf("0x%04x | ", (int) i);
} while (++ i);
}
(I cannot check here, as I have z80 computer, but not a C compiler for it)
Edit
After checking the assembler code, the compiler output just pushes the complete bc register into the stack, in which the lower part (thec register) comes from the character you want to print, but the b register was previously loaded with the high byte of the 59999 pointer to the array of characters of the format string, which happens to be 0xea. So, I got stranged at the output, that should be probably 0xea00, 0xea01, 0xea02, ... and not the output you have. Have you recompiled the source to get the assembler output and the output refers to a different compilation?
To dig a little more I'd need the code of the printf() function, which I assume you don't have. But that seems that converting the parameter to (int) before passing it to the printf() function should solve the problem.

Powerpivot 2016 measure using DAX to sum an array

I want to sum the 7 preceding values of a row as a measure like so:
| Wk_number | Value A | Measure | Array |
-------------------------------------------
| 01 | 1 | N/A# | N/A# |
| 02 | 1 | 1 | {01} |
| 03 | 10 | 2 | {01-02} |
| 04 | 3 | 12 | {01-03} |
| 05 | 5 | 15 | {01-04} |
| 06 | 10 | 20 | {01-05} |
| 07 | 1 | 30 | {01-06} |
| 08 | 4 | 31 | {01-07} |
| 09 | -10 | 34 | {02-08} |
| 10 | 3 | 26 | {03-09} |
| 11 | 2 | 18 | {04-10} |
etc...
I added the array column just to clarify the example how of the sum is comprised, notice that from wk09 it's not simply a running total.
How to do this using DAX statements?
Two ways to do this: you can either create a calculated column, or a measure.
For the column:
=CALCULATE(SUM([Value A]),FILTER(Table,Table[Wk_number]<EARLIER(Table[Wk_number]) && Table[Wk_number] >= (EARLIER(Table[Wk_number])-7)))
For the measure, it's a very similar formula but instead of using EARLIER(), we use MAX():
=CALCULATE(SUM([Value A]),FILTER(ALL(Table3),Table3[Wk_number]<MAX(Table3[Wk_number]) && Table3[Wk_number] >= (MAX(Table3[Wk_number])-7)))
Below is a screenshot of the results. A few of the numbers in your example table seem to be off based on the math:

Multiple outcomes/scenarios

I got a problem that I have already created a solution for, but I'm wondering if there's a better way of solving the problem. Basically I have to create a flag for certain scenarios under a partition of ID and date. My solution involved mapping for all the possible scenarios, then creating "case when" statements for all these scenarios with the specific outcome. Basically, I was the one that created the outcomes. I am wondering if there's another way, something around letting SQL create the outcomes instead of myself.
Thanks a lot!
Background:
+----+-----------+--------+-------+------+-----------------+-----------------------------------------------------------------------------------+
| ID | Month | Status | Value | Flag | Scenario Number | Scenario Description |
+----+-----------+--------+-------+------+-----------------+-----------------------------------------------------------------------------------+
| 1 | 1/01/2016 | First | 123 | No | 1 | First, second and blank exists. Do not flag |
| 1 | 1/01/2016 | Second | 456 | No | 1 | First, second and blank exists. Do not flag |
| 1 | 1/01/2016 | | 789 | No | 1 | First, second and blank exists. Do not flag |
| 1 | 1/02/2016 | Second | 123 | Yes | 2 | First does not exist, two second but have different values. Flag these as Yes |
| 1 | 1/02/2016 | Second | 456 | Yes | 2 | First does not exist, two second but have different values. Flag these as Yes |
| 1 | 1/02/2016 | Second | 123 | No | 3 | First does not exist, two second have same values. Do not flag |
| 1 | 1/02/2016 | Second | 123 | No | 3 | First does not exist, two second have same values. Do not flag |
| 1 | 1/03/2016 | Second | 123 | No | 4 | Only one entry of Second exist. Do no flag |
| 1 | 1/04/2016 | | 123 | Yes | 5 | Two blanks for the partition. Flag these as Yes |
| 1 | 1/04/2016 | | 123 | Yes | 5 | Two blanks for the partition. Flag these as Yes |
| 1 | 1/05/2016 | | | No | 6 | Only one entry of blank exist. Do not flag these |
| 1 | 1/06/2016 | First | 123 | Yes | 7 | First exist for the partition. Do not flag |
| 1 | 1/06/2016 | | 456 | Yes | 7 | First exist for the partition. Do not flag |
| 1 | 1/07/2016 | Second | 123 | Yes | 8 | First does not exist and second and blank do not have the same value. Flag these. |
| 1 | 1/07/2016 | | 456 | Yes | 8 | First does not exist and second and blank do not have the same value. Flag these. |
| 1 | 1/07/2016 | Second | 123 | Yes | 8 | First does not exist and second and blank have the same value. Flag these. |
| 1 | 1/07/2016 | | 123 | Yes | 8 | First does not exist and second and blank have the same value. Flag these. |
+----+-----------+--------+-------+------+-----------------+-----------------------------------------------------------------------------------+
Data:
+----+-----------+-------+----------+---------------+
| ID | Month | Value | Priority | Expected_Flag |
+----+-----------+-------+----------+---------------+
| 1 | 1/01/2016 | 96.01 | | Yes |
| 1 | 1/01/2016 | 96.01 | | Yes |
| 1 | 1/02/2016 | 65.2 | First | No |
| 1 | 1/02/2016 | 3.47 | Second | No |
| 1 | 1/02/2016 | 45.99 | | No |
| 11 | 1/01/2016 | 25 | | No |
| 11 | 1/02/2016 | 74.25 | Second | No |
| 11 | 1/02/2016 | 74.25 | Second | No |
| 11 | 1/02/2016 | 23.25 | | No |
| 24 | 1/01/2016 | 1.25 | First | No |
| 24 | 1/01/2016 | 1.365 | | No |
| 24 | 1/04/2016 | 1.365 | First | No |
| 24 | 1/04/2016 | 1.365 | | No |
| 24 | 1/05/2016 | 1.365 | First | No |
| 24 | 1/05/2016 | 1.365 | First | No |
| 24 | 1/06/2016 | 1.365 | Second | No |
| 24 | 1/06/2016 | 1.365 | Second | No |
| 24 | 1/07/2016 | 1.365 | Second | Yes |
| 24 | 1/07/2016 | 1.365 | | Yes |
| 24 | 1/08/2016 | 1.365 | First | No |
| 24 | 1/08/2016 | 1.365 | | No |
| 24 | 1/09/2016 | 1.365 | Second | No |
| 24 | 1/09/2016 | 1.365 | | No |
| 27 | 1/01/2016 | 0 | Second | Yes |
| 27 | 1/01/2016 | 0 | Second | Yes |
| 27 | 1/02/2016 | 45.25 | Second | No |
| 3 | 1/01/2016 | 96.01 | First | No |
| 3 | 1/01/2016 | 96.01 | First | No |
| 3 | 1/03/2016 | 96.01 | First | No |
| 3 | 1/03/2016 | 96.01 | First | No |
| 35 | 1/01/2016 | | | Yes |
| 35 | 1/01/2016 | | | Yes |
| 35 | 1/02/2016 | | First | No |
| 35 | 1/02/2016 | | Second | No |
| 35 | 1/02/2016 | | | No |
| 35 | 1/02/2016 | | | No |
| 35 | 1/03/2016 | | Second | Yes |
| 35 | 1/03/2016 | | Second | Yes |
| 35 | 1/04/2016 | | Second | No |
| 35 | 1/04/2016 | | Second | No |
+----+-----------+-------+----------+---------------+

Resources