Question

I am working on a PHP program that reads from a FoxPro system. I am not allowed to modify the foxpro system as it is used for daily operations. So I have been using the ODBC driver with much success. The system I am currently working on requires me to create a union and show the data in a specific order. I have this query thus far:

SELECT arinvt01.item as recipe_group, arinvt01.item, arinvt01.descrip, arinvt01.cost, arinvt01.code as rcode
FROM arinvt01
WHERE code = 'RW'
UNION ALL
SELECT arrecp01.item as recipe_group, arinvt01.item, arinvt01.descrip, arinvt01.cost, arinvt01.code as rcode
FROM arinvt01
  INNER JOIN arrecp01 ON (arrecp01.recipe = arinvt01.item)
WHERE arrecp01.item IN (
    SELECT item
    FROM arinvt01
    WHERE code = 'RW'
)
ORDER BY recipe_group

The first SELECT fetches the RAW items from the table while the second SELECT fetches the items that use the RAW items (the table arrecp01 stores the associations for the items to the RAW items.) I am trying to list all items and categorize them by the RAW item so we can see all the items used for each RAW item. This means some items will be in more than one RAW item. I basically want the RAW item listed first for each recipe_group.

This returns (only showing 20 rows):

recipe_group    item            descrip                             cost    rcode
ALMORAW         RCHKI10OZTR     RETAIL CHINA KISS 10OZ CASE         16.769
ALMORAW         ALMORAW         ALMONDS RAW                         2.32    RW
ALSPRAW         ALSP            ALFALFA SPROUTS                     1.44
ALSPRAW         ALSPLBS         ALFALFA SPROUT LBS                  1.44
ALSPRAW         ALSPRAW         ALFALFA SPROUTS RAW                 1.44    RW
ALSPRAW         ALSP4OZEA       ALFALFA SPROUT 4OZ                  0.486
APPLEGRRAW      FAPGDI250PLD5T  FRUIT APPLE GR. DICE PLD 1/4" 5#TR  9.26
APPLEGRRAW      FAPGWEDGE3B     FRUIT APPLE GREEN WEDGE 3#          4.893
APPLEGRRAW      FAPGRSL250SYS   6485249 APPLE GREEN SLICE 1/4" 20#  52.415
APPLEGRRAW      APPLEGRSL8MIX   APPLE GREEN SLICES INTO 8 MIX       5.457
APPLEGRRAW      FAPGRWEDGE502   FRUIT APPLE GREEN WEDGE 50/2oz CASE 15.398
APPLEGRRAW      FAPGDI2505B     FRUIT APPLE GREEN DICE 1/4" 5# BAG  7.81
APPLEGRRAW      FAPGWE2200CS    FRUIT APPLE GR. WEDGE 200/2oz  CS   47.51
APPLEGRRAW      FAPGRPESLSYS    APPLE GR. SLICED PLD/CRD 1/8" 2/5#  26.455
APPLEGRRAW      APGSDI10        APPLES "GRANNY SMITH" DICED 1/4"    1.423
APPLEGRRAW      FAPGRWEDGE4OZ   FRUIT APPLE GREEN WEDGE 4oz EACH    0.222
APPLEGRRAW      FAPGDI250       FRUIT APPLE GREEN DICE 1/4"         1.801
APPLEGRRAW      FAPGSLHM5B      FRUIT APPLE GREEN HALFMOON 5#       8.446
APPLEGRRAW      FAPGPC5B        FRUIT APPLE GREEN PEELED/CORED 5#   8.173
APPLEGRRAW      APGDI5005B      APPLE GREEN DICED 1/2" 5# BAG       4.795

I imported these tables into MySQL for testing the data and in MySQL I can use this query to get the results as I need them.

SELECT arinvt01.item as recipe_group, arinvt01.item, arinvt01.descrip, arinvt01.cost, arinvt01.code as rcode
FROM arinvt01
WHERE code = 'RW'
UNION ALL
SELECT arrecp01.item as recipe_group, arinvt01.item, arinvt01.descrip, arinvt01.cost, arinvt01.code as rcode
FROM arinvt01
    INNER JOIN arrecp01 ON (arrecp01.recipe = arinvt01.item)
WHERE arrecp01.item IN (
        SELECT item
        FROM arinvt01
        WHERE code = 'RW'
)
ORDER BY recipe_group, (rcode = 'RW') desc

Adding , (code = 'RW') desc to the ORDER BY claus returns the results exactly as I need them. It also works in MySQL with ORDER BY recipe_group, CASE tcode WHEN 'RW' THEN 2 ELSE 3 END.

This returns (only showing 20 rows):

recipe_group    item            descrip                             cost    rcode
ALMORAW         ALMORAW         ALMONDS RAW                         2.32    RW
ALMORAW         RCHKI10OZTR     RETAIL CHINA KISS 10OZ CASE         16.769    
ALSPRAW         ALSPRAW         ALFALFA SPROUTS RAW                 1.44    RW
ALSPRAW         ALSP            ALFALFA SPROUTS                     1.44      
ALSPRAW         ALSPLBS         ALFALFA SPROUT LBS                  1.44      
ALSPRAW         ALSP4OZEA       ALFALFA SPROUT 4OZ                  0.486     
APPLEGRRAW      APPLEGRRAW      APPLE GREEN (    CS    #/CS) LB RAW 0.625   RW
APPLEGRRAW      FAPGDI250PLD5T  FRUIT APPLE GR. DICE PLD 1/4" 5#TR  9.26      
APPLEGRRAW      FAPGWEDGE3B     FRUIT APPLE GREEN WEDGE 3#          4.893     
APPLEGRRAW      FAPGRSL250SYS   6485249 APPLE GREEN SLICE 1/4" 20#  52.415    
APPLEGRRAW      APPLEGRSL8MIX   APPLE GREEN SLICES INTO 8 MIX       5.457     
APPLEGRRAW      FAPGRWEDGE502   FRUIT APPLE GREEN WEDGE 50/2oz CASE 15.398    
APPLEGRRAW      FAPGDI2505B     FRUIT APPLE GREEN DICE 1/4" 5# BAG  7.81      
APPLEGRRAW      FAPGWE2200CS    FRUIT APPLE GR. WEDGE 200/2oz  CS   47.51     
APPLEGRRAW      FAPGRPESLSYS    APPLE GR. SLICED PLD/CRD 1/8" 2/5#  26.455    
APPLEGRRAW      APGSDI10        APPLES "GRANNY SMITH" DICED 1/4"    1.423     
APPLEGRRAW      FAPGRWEDGE4OZ   FRUIT APPLE GREEN WEDGE 4oz EACH    0.222     
APPLEGRRAW      FAPGDI250       FRUIT APPLE GREEN DICE 1/4"         1.801     
APPLEGRRAW      FAPGSLHM5B      FRUIT APPLE GREEN HALFMOON 5#       8.446     
APPLEGRRAW      FAPGPC5B        FRUIT APPLE GREEN PEELED/CORED 5#   8.173     

When I do this with the foxpro ODBC driver I get the following error: [Microsoft][ODBC Visual FoxPro Driver]SQL: ORDER BY clause is invalid. or when using the CASE I get [Microsoft][ODBC Visual FoxPro Driver]Command contains unrecognized phrase/keyword.

Update IIF throws the error: [Microsoft][ODBC Visual FoxPro Driver]SQL: ORDER BY clause is invalid.

Is it possible to get these results using the ODBC driver for foxpro? When I checked the syntax for the SELECT structure I noticed it does allow multiple column ORDER BY but like I said, I keep getting a error.

It should be noted that RAW items have a code of RW while most have no code and some have other values for code (EQ,EA,PA to name a few.) I only want RW to be listed first, the rest are irrelevant for this system.

Perhaps I am missing something so thought I'd ask here for some help on this matter.

Thanks

I am using the ADOdb Database Abstraction Library for PHP if this helps.

Not sure if necessary but just to be safe. Tables structure:

arinvt01

CREATE TABLE IF NOT EXISTS `arinvt01` (
  `item` varchar(15) NOT NULL DEFAULT '',
  `class` varchar(2) DEFAULT NULL,
  `descrip` varchar(35) DEFAULT NULL,
  `cost` double(12,4) DEFAULT NULL,
  `onhand` double(12,3) DEFAULT NULL,
  `onorder` double(12,3) DEFAULT NULL,
  `aloc` double(12,3) DEFAULT NULL,
  `wip` double(12,3) DEFAULT NULL,
  `price` double(12,4) DEFAULT NULL,
  `price1` double(12,4) DEFAULT NULL,
  `price2` double(12,4) DEFAULT NULL,
  `level2` double(12,3) DEFAULT NULL,
  `price3` double(12,4) DEFAULT NULL,
  `level3` double(12,3) DEFAULT NULL,
  `ptdqty` double(12,3) DEFAULT NULL,
  `ytdqty` double(12,3) DEFAULT NULL,
  `ptdsls` double(12,2) DEFAULT NULL,
  `ytdsls` double(12,2) DEFAULT NULL,
  `discrate` double(7,3) DEFAULT NULL,
  `unitms` varchar(2) DEFAULT NULL,
  `code` varchar(2) DEFAULT NULL,
  `type` varchar(5) DEFAULT NULL,
  `seq` varchar(5) DEFAULT NULL,
  `ldate` date DEFAULT NULL,
  `lastordr` date DEFAULT NULL,
  `orderpt` double(12,3) DEFAULT NULL,
  `orderqty` double(12,3) DEFAULT NULL,
  `supplier` varchar(6) DEFAULT NULL,
  `vpartno` varchar(15) DEFAULT NULL,
  `lead` double(3,0) DEFAULT NULL,
  `gllink` varchar(3) DEFAULT NULL,
  `decnum` double(1,0) DEFAULT NULL,
  `taxcode` varchar(1) DEFAULT NULL,
  `stkcode` varchar(1) DEFAULT NULL,
  `history` varchar(1) DEFAULT NULL,
  `weight` double(12,4) DEFAULT NULL,
  `req1` double(12,3) DEFAULT NULL,
  `rec1` double(12,3) DEFAULT NULL,
  `req2` double(12,3) DEFAULT NULL,
  `rec2` double(12,3) DEFAULT NULL,
  `req3` double(12,3) DEFAULT NULL,
  `rec3` double(12,3) DEFAULT NULL,
  `req4` double(12,3) DEFAULT NULL,
  `rec4` double(12,3) DEFAULT NULL,
  `req5` double(12,3) DEFAULT NULL,
  `rec5` double(12,3) DEFAULT NULL,
  `req6` double(12,3) DEFAULT NULL,
  `rec6` double(12,3) DEFAULT NULL,
  `signature` double(2,0) DEFAULT NULL,
  `price4` double(12,2) DEFAULT NULL,
  `level4` double(12,3) DEFAULT NULL,
  `price5` double(12,2) DEFAULT NULL,
  `level5` double(12,3) DEFAULT NULL,
  `price6` double(12,2) DEFAULT NULL,
  `level6` double(12,3) DEFAULT NULL,
  `price7` double(12,2) DEFAULT NULL,
  `level7` double(12,3) DEFAULT NULL,
  `price8` double(12,2) DEFAULT NULL,
  `level8` double(12,3) DEFAULT NULL,
  `price9` double(12,2) DEFAULT NULL,
  `level9` double(12,3) DEFAULT NULL,
  `olddate` date DEFAULT NULL,
  `qoitem` varchar(1) DEFAULT NULL,
  `shortdesc` varchar(17) DEFAULT NULL,
  `lotcode` varchar(1) DEFAULT NULL,
  `prlist` varchar(1) DEFAULT NULL,
  `cubic` double(6,2) DEFAULT NULL,
  `fprice` double(12,2) DEFAULT NULL,
  `fprice1` double(12,2) DEFAULT NULL,
  `fprice2` double(12,2) DEFAULT NULL,
  `fprice3` double(12,2) DEFAULT NULL,
  `fprice4` double(12,2) DEFAULT NULL,
  `fprice5` double(12,2) DEFAULT NULL,
  `fprice6` double(12,2) DEFAULT NULL,
  `fprice7` double(12,2) DEFAULT NULL,
  `fprice8` double(12,2) DEFAULT NULL,
  `fprice9` double(12,2) DEFAULT NULL,
  `salesmn` varchar(2) DEFAULT NULL,
  `recipe` varchar(1) DEFAULT NULL,
  `upccode` varchar(15) DEFAULT NULL,
  `packaging` varchar(1) DEFAULT NULL,
  `umqty` double(3,0) DEFAULT NULL,
  `umdesc` varchar(6) DEFAULT NULL,
  `duty` double(6,2) DEFAULT NULL,
  `itemno` varchar(15) DEFAULT NULL,
  `factor` double(12,5) DEFAULT NULL,
  `beginvt` double(12,3) DEFAULT NULL,
  `endinvt` double(12,3) DEFAULT NULL,
  `phydate` date DEFAULT NULL,
  `comment` varchar(65) DEFAULT NULL,
  `onhwght` double(12,2) DEFAULT NULL,
  `edited` datetime DEFAULT NULL,
  `editedby` varchar(10) DEFAULT NULL,
  `edworkst` varchar(10) DEFAULT NULL,
  `lastcost` double(10,3) DEFAULT NULL,
  `buyer` varchar(10) DEFAULT NULL,
  `unitqty` double(10,2) DEFAULT NULL,
  PRIMARY KEY (`item`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

arrecp01

CREATE TABLE IF NOT EXISTS `arrecp01` (
    `recipe` varchar(15) DEFAULT NULL,
  `item` varchar(15) DEFAULT NULL,
  `descrip` varchar(35) DEFAULT NULL,
  `qty` double(12,3) DEFAULT NULL,
  `cost` double(12,3) DEFAULT NULL,
  `entered` date DEFAULT NULL,
  `signature` double(2,0) DEFAULT NULL,
  KEY `item_recipe` (`item`,`recipe`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Was it helpful?

Solution

Well, first, it definitely smells of SBT Accounting system which I specialized in throughout the 90's. Anyhow, you should be able to get away with a LEFT-JOIN to the recipe table.

As for the order by, yes, VFP/ODBC (I have used the Microsoft Visual Foxpro OleDB provider with C#), allows you to use the alias column name as the group by clause, so here, I have the same recipe_group basis, but if there is a "recipe", the NVL() will grab the recipe item value instead of the actual item for grouping purposes. THEN grab the item, etc...

So the order by is based o the recipe_group, then the second is base on an IIF(). If the code is that of 'RW', then put it 1st (via 1) else second (via 2). So now, within, given recipe all the 1 entries are at the top, then all others. After that secondary level of sorting, then the items will be listed in alpha order.

SELECT
      NVL( rcp.item, ari.item ) as recipe_group,
      IIF( ari.code = 'RW', 1, 2 ) as RWSort,
      ari.item,
      ari.descrip,
      ari.cost,
      ari.code as rcode
   from
      arinvt01 ari
         LEFT JOIN arrecp01 rcp
            ON ari.item = rcp.recipe
   where
      ari.code = 'RW'
   order by
      recipe_group,
      RWSort,
      ari.item

OTHER TIPS

First, try to use AS clause after IIF, e.g.:

IIF(ari.code = 'RW', 1, 2) AS field1

Also, you could possibly run your query w/o IIF statement, then run the following UPDATES:

UPDATE ari SET field1=1 WHERE code='RW'
UPDATE ari SET field1=2 WHERE code<>'RW'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top