-1

解決を試みるための完全な例が提供されています。問題は、2 つの列 ('MUNTAX' AND 'SCHTAX') を追加し、結果をテーブル ('house') の 3 番目の列 ('TOTALTAX') に入れたいことです。ただし、列は整数ではなく varchar 型の価格であるため、計算する前に「$」記号と「,」を削除する必要があります。計算後、'$' と ',' を足し合わせた合計を varchar に戻す必要があります。

私がハングアップしているのは、合計を取得することです。

テーブルを作成します。

CREATE TABLE `house` (
`ID` int(10) unsigned NOT NULL auto_increment,
`MLS_NO` int(10) default NULL,
`AGENT` varchar(120) default NULL,
`DISP_ORDER` int(4) default NULL,
`ADDR` varchar(200) NOT NULL default '',
`PRICE` varchar(12) NOT NULL default '',
`PRTYPE` varchar(20) default NULL,
`BUILTYPE` varchar(30) default NULL,
`YEAR` varchar(4) default NULL,
`LAREA` decimal(10,0) default NULL,
`ROOM` decimal(10,0) default NULL,
`BEDROOM` decimal(10,0) default NULL,
`BATHROOM` decimal(10,0) default NULL,
`PWDRROOM` decimal(10,0) default NULL,
`GARAGE` decimal(10,0) default NULL,
`PARKING` decimal(10,0) default NULL,
`MUNTAX` varchar(30) default NULL,
`SCHTAX` varchar(30) default NULL,
`TOTALTAX` varchar(30) default NULL,
`DESCR` text,
`DEFAULTPIC` decimal(10,0) default NULL,
`ADTYPE` varchar(100) default NULL,
`DESCR_2` text,
PRIMARY KEY  (`ID`),
KEY `Index_2` (`ADDR`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=122 ;

INSERT INTO `house` (`ID`, `MLS_NO`, `AGENT`, `DISP_ORDER`, `ADDR`, `PRICE`, `PRTYPE`, `BUILTYPE`, `YEAR`, `LAREA`, `ROOM`, `BEDROOM`, `BATHROOM`, `PWDRROOM`, `GARAGE`, `PARKING`, `MUNTAX`, `SCHTAX`, `TOTALTAX`, `DESCR`, `DEFAULTPIC`, `ADTYPE`, `DESCR_2`) VALUES (110, 8620825, 'N', NULL, '5871 FL', '$1,025,000.0', 'DETACHED', 'COTTAGE', NULL, '589', '10', '4', '3', '1', NULL, '4', '$7,774.42', NULL, 'NULL', 'Beautiful');

ストアド プロシージャ:

DELIMITER $$
DROP PROCEDURE IF EXISTS TotalTaxProc $$

CREATE PROCEDURE TotalTaxProc(IN MLS INT(10), OUT MUNFLO FLOAT(10), OUT SCHINT FLOAT(10), OUT TOTTAX VARCHAR(10))
BEGIN
DECLARE SCH VARCHAR(30);
DECLARE MUN VARCHAR(30);

SET SCHFLO=0.0;
SET MUNFLO=0.0;
SET TOTTAX='';

SELECT MUNTAX FROM house WHERE MLS_NO=MLS INTO MUN;
SELECT SCHTAX FROM house WHERE MLS_NO=MLS INTO SCH;

SET MUNFLO=IFNULL(REPLACE(REPLACE(MUN, '$', ''), ',', ''), 0);
SET SCHFLO=IFNULL(REPLACE(REPLACE(SCH, '$', ''), ',', ''), 0);

SET TOTTAX=CONCAT('$', MUNFLO + SCHFLO ) ;

SET TOTTAX=CONCAT(SUBSTRING_INDEX(TOTTAX, SUBSTRING(TOTTAX, -6), 1),',',SUBSTRING(TOTTAX, -6) );


UPDATE house SET TOTALTAX=TOTTAX WHERE MLS_NO=MLS;
END $$
DELIMITER ;

そして最後に呼び出し、

CALL TotalTaxProc(8620825,@MUNINT,@SCHINT,@TOTTAX);
SELECT @MUNINT,@SCHINT,@TOTTAX;

したがって、明らかに、TOTTAX が '$7,774.42' を与えるはずのコンマだけを取得します。

4

2 に答える 2

0

@TOTTAX ユーザー変数を設定しているコードのどこにも表示されません。(同様の名前のプロシージャ変数 TOTTAX を変更していますが、呼び出しと選択を除いて、ユーザー変数 @TOTTAX への参照はどこにもありません。)

これらすべての SUBSTRING および SUBSTRING_INDEX 関数ではなく、使用できない FORMAT 関数に問題がありますか?

SET TOTTAX=CONCAT('$',FORMAT(MUNFLO+SCHFLO,2));

FORMAT() 関数は、10 進数の後に 2 つの数字があり、コンマ区切り記号が追加されていることを確認する必要があります。これらすべてSUBSTRINGSUBSTRING_INDEXインデックス関数を使用する必要はありません。


ここで spacediver のコメントを繰り返します。UPDATE ステートメントは、house テーブルのすべての行を同じ値で更新するように見えます。(それは間違っていないかもしれませんが、奇妙に奇妙に思えます。UPDATE ステートメントのほとんどで、更新する行を指定する何らかの述語である JOIN または WHERE 句を持たないのは間違っています。)


アップデート

質問を更新しました(いくつかの重要な改善を行いました)

(おそらく) 同じ行から異なる列を取得するために 2 つの別々のクエリを実行しているのは奇妙です。これらの 2 つの別個のステートメント:

SELECT MUNTAX FROM house WHERE MLS_NO=MLS INTO MUN;
SELECT SCHTAX FROM house WHERE MLS_NO=MLS INTO SCH;

単一の選択に置き換えることができます:

SELECT MUNTAX, SCHTAX FROM house WHERE MLS_NO=MLS INTO MUN,SCH;

私が知る限り、この行:

SET TOTTAX=CONCAT(SUBSTRING_INDEX(TOTTAX, SUBSTRING(TOTTAX, -6), 1),',',SUBSTRING(TOTTAX, -6) );

有用なことは何もしません。(これが何をする必要があるか、関数があなたのためにできないことをチェックする必要があるかはまったく明確ではFORMAT()ありません。なぜ行が必要なのですか、それは何をしているはずですか?

(明らかに) フォーマットされた文字列 (ACCCKKK!) として格納されている 10 進数値を値にキャストしているように見えますがINTEGER、これは基本的に小数点以下 2 桁を失っています。

次に、行内の他の 2 つの値の合計として値を計算し、その結果を「書式設定された」文字値として TOTALTAX 列に割り当てます。不思議なことに、INTEGER 値を SCHTAX (文字) 列に割り当てています。これは、以前は書式設定された文字列として 10 進数値であると予想されていました。

「最終的な解決策」のコードは、マスターに合格しません。

単一の SQL ステートメントでこれほど簡単に実行できる (そして簡単に理解できる) ものは、ここで達成されているとは思いません。

MLS_NO 列が一意である (または、行に既に存在する値を使用して単一の行を更新しようとしている) と仮定すると、

CREATE PROCEDURE TotalTaxProc(IN MLS INT(10))
BEGIN

UPDATE house
   SET TOTALTAX = CONCAT('$',FORMAT(
         IFNULL(REPLACE(REPLACE(MUNTAX, '$', ''), ',', ''), 0) 
       + IFNULL(REPLACE(REPLACE(SCHTAX, '$', ''), ',', ''), 0)
       ,2))
 WHERE MLS_NO=MLS;

END $$

これは、すべてのプロシージャ変数と SET ステートメント、およびすべての回転がなくても、非常に理解しやすいものです

同じ MLS_NO を持つ行が複数ある場合、このステートメントはプロシージャーとは動作が異なります。

このステートメントは、同じ行の値から派生した TOTALTAX 列に値を割り当てます。一方、プロシージャは、一致する MLS_NO を持つ1 つの行の値を使用して、同じ一致する MLS_NO を持つすべての行を更新します。(MLS_NO が一意であれば違いはありません。一意でなければ違いがあります。)

これは、TOTALTAX に割り当てられる値の計算で小数点以下の桁数が失われないという点で、「最終的なソリューション」のコードとも異なります (簡単に追加できます)。(数字をなくしたい場合、それらを足し合わせる前にそれをしたいですか、それとも足し算をした後にそれらを失いたいですか.

また、このステートメントは、SCHTAX 列の値を再フォーマットしないという点でも異なります。(この動作は、同じステートメントに簡単に追加するだけで簡単に追加できます。)

あなたの手順は、SCHTAX 列の値を、たとえば '$6,543.21' から '6543' に変更しますが、なぜそれを行う必要があるのか​​まったく明確ではありません。(SCHTAX と MUNTAX の文字列値に、 のような数値ではない何か'/yr'' per year'または' (paid 2012)'無視しようとしている何かがある可能性があると考えていました。


于 2012-07-19T22:08:22.677 に答える
0

最終的解決:

DELIMITER //
DROP PROCEDURE IF EXISTS TotalTaxProc //

CREATE PROCEDURE TotalTaxProc(IN MLS INT(10))
BEGIN
DECLARE SCH VARCHAR(30);
DECLARE MUN VARCHAR(30);
DECLARE SCHFLO FLOAT(15,2);
DECLARE MUNFLO FLOAT(15,2);
DECLARE TOTTAX VARCHAR(30);

SET SCHFLO=0.00;
SET MUNFLO=0.00;
SET TOTTAX='';

SELECT MUNTAX FROM HOUSE WHERE MLS_NO=MLS INTO MUN;
SELECT SCHTAX FROM HOUSE WHERE MLS_NO=MLS INTO SCH;

SET MUNFLO=CAST( IFNULL(REPLACE(REPLACE(MUN, '$', ''),',',''), '0.00') * 100 AS DECIMAL);
SET SCHFLO=CAST( IFNULL(REPLACE(REPLACE(SCH, '$', ''),',',''), '0.00') * 100 AS DECIMAL);


SET TOTTAX=CONCAT('$',FORMAT(MUNFLO/100+SCHFLO/100,2));


UPDATE HOUSE SET TOTALTAX=TOTTAX WHERE MLS_NO=MLS;
END //
DELIMITER ;

そして呼び出し:

CALL TotalTaxProc(8620825);
于 2012-07-20T13:03:17.697 に答える